我试图让这个 OSX 代码(为了便于讨论而打高尔夫球)在 Ubuntu Linux 上工作。
cat >main.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void provided_by_main() { puts("Hello main!"); }
int main() {
void *provider_so, *needer_so;
(provider_so = dlopen("provider.so", RTLD_NOW)) || printf("Fail %s\n", dlerror()) && (exit(0),0);
(needer_so = dlopen("needer.so", RTLD_NOW)) || printf("Fail %s\n", dlerror()) && (exit(0),0);
void (*needer)() = dlsym(needer_so, "needer");
needer();
}
EOF
cat >needer.c <<EOF
extern void provider();
void needer() { provider(); }
EOF
cat >provider.c <<EOF
#include <stdio.h>
void provider() { puts("Hello provider!"); }
EOF
gcc -shared -o provider.so provider.c
gcc -shared -o needer.so needer.c -dynamic -undefined dynamic_lookup
gcc -o main main.c -ldl
./main
Hello provider!
在 Linux 上,通过反复试验和 StackOverflow,我确定needer
不能引用中定义的任何内容,main
除非main
已链接-rdynamic
:
gcc -shared -fpic -o provider.so provider.c
gcc -shared -fpic -o needer.so needer.c -Dprovider=provided_by_main
gcc -o main main.c -ldl -rdynamic
./main
Hello main!
但是,needer
即使provider
整个“链”编译为-rdynamic
:
gcc -shared -fpic -o provider.so provider.c -rdynamic
gcc -shared -fpic -o needer.so needer.c
gcc -o main main.c -ldl -rdynamic
./main
Fail needer.so: undefined symbol: provider
那么,我该如何进行这项工作呢?
或者,如果它在 Linux 上的设计是不可能的,那为什么它被设计成不可能的呢?
(OSX 等价物:从 OS X 上的 C 中的 dlopen()ed 动态库访问主程序全局变量)
现实世界的额外复杂性:在我的实际程序中,provider.so
是在运行时生成的代码,并且在链接provider
之后才确定符号的名称。main
但是,即使是涉及修改的答案也main.c
将是朝着正确方向迈出的一步。