有没有办法动态链接具有依赖关系的共享库?
例如,我有两个库,libA.so和libB.so. libB.so调用libA.so中定义的函数。
在我的主程序中,我希望用dlopen加载这两个库。但是,如果我尝试:
dlopen(libA.so);
dlopen(libB.so);
然后第二个dlopen将失败,因为libB具有无法识别的符号。
我可以想到一些解决方法,例如将所有目标文件构建到单个共享库中,或者让libB.so在libA.so上调用dlopen,但这是额外的工作。
我想我想象这个工作的方式就像内核模块一样,你可以使用" EXPORT_SYMBOL()"允许其他模块调用先前加载的模块中定义的函数。
可以使用共享库完成类似的操作吗?或者我必须使用我的解决方法吗?
答案 0 :(得分:2)
我遇到了类似的情况,这对我有用(使用gcc工具链):
创建共享对象libB.so
时,无条件地链接库libA.so
,命令应如下所示:
gcc -shared -Wl,--no-as-needed -lA -o libB.so b.o
然后,您可以检查libA.so
是否确实成为动态链接器的依赖项:
$ ldd libB.so
linux-gate.so.1 => (0xb77ba000)
libA.so => not found
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75f7000)
/lib/ld-linux.so.2 (0xb77bb000)
在主程序中,仅dlopen()
库libB.so
就足够了,而另一个库应该由动态链接器自动链接。
答案 1 :(得分:1)
您是否尝试过使用RTLD_GLOBAL?
<强> RTLD_GLOBAL 强> 此库定义的符号将可用于后续加载的库的符号解析。
即使B依赖于A:
,这也应该可以正常工作void * const handleA = dlopen("libA.so", RTLD_NOW | RTLD_GLOBAL);
void * const handleB = dlopen("libB.so", RTLD_NOW);