【发布时间】:2013-08-02 23:40:02
【问题描述】:
我正在尝试让这个 OSX 代码(golfed 便于讨论)在 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!
但是,即使整个“链”是用-rdynamic 编译的,我也无法让needer 看到provider 提供的任何内容:
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 等效:Accessing main program global variables from a dlopen()ed dynamic library in C on OS X)
现实世界的额外复杂性:在我的实际程序中,provider.so 是在运行时生成的代码,provider 符号的名称直到 main 之后才确定被链接了。但是,即使是涉及修改main.c 的答案也是朝着正确方向迈出的一步。
【问题讨论】:
标签: c linux shared-libraries elf dlopen