想象 Library1.so 和 Library2.so 具有:
func1(), func2(), glob_data1, glob_data2
情况:
我想在 Library1 ,
中使用func1()
和glob_data1
并同时在 Library2 中使用func2()
和glob_data2
。
问题:
动态链接这些库时该怎么办?
(如果在C级上没有办法,那么在汇编级上有没有办法?)
答案 0 :(得分:2)
假设
Library1.so
和Library2.so
具有:func1(), func2(), glob_data1, glob_data2
在Linux(和其他UNIX系统)上将两个库都加载到一个进程中通常是一个非常不好的主意。
例如func1
中的library1
呼叫func2
,哪个func2
被呼叫?答案取决于确切的链接方式,库的加载方式和顺序。
如果函数未调用任何其他导出的符号,则可以 通过从dlopen
和dlsym
获得的函数指针对其进行调用:
void *h1 = dlopen("Library1.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L1)(void) = dlsym(h1, "func1");
void *h2 = dlopen("Library2.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L2)(void) = dlsym(h2, "func1");
printf("func1 from Library1 returns %d\n", f1L1());
printf("func1 from Library2 returns %d\n", f1L2());
答案 1 :(得分:1)
如果这些符号不打算在库外使用,则可以将它们标记为__attribute((visibility("hidden")))
(或者最好用-fvisibility=hidden
编译代码,并用__attribute((visibility("default")))
注释公共函数)
如果必须公开这些功能,则可以使用-symbolic
标志链接您的库。这将导致链接程序在可能的情况下解析对本地定义(而不是PLT存根)的引用。
请注意,-symbolic
适用于所有库符号。可以使用符号别名对符号子集实现相同的效果,但这涉及更多,因此除非您确实需要,否则我不愿赘述。