假设我有一个库libfoo.so.1
,它取决于(ldd
)libbar.so.1
。但是,libbar.so.1
目前无法使用。我的应用需要调用libfoo.so.1
中的函数,该函数根本不需要libbar.so.1
。
有没有办法加载libfoo.so.1
,解析函数符号然后调用它而不需要libbar.so.1
来满足依赖性?这是“我知道我在做什么,只是让我这样做”的案例。我尝试了RTLD_LAZY标志,但在不加载符号之前,它仍尝试加载libbar.so.1
库。
修改的
这是确切的情况。
我们有3名球员:
libbar.so.1
,位于不在LD_LIBRARY_PATH
或ldconfig
内的路径中的共享库,其依赖项已全部解析libfoo.so.1
,位于与libbar
不同的目录中的共享库,但依赖于libbar
。在运行时,libfoo
将知道在哪里找到libbar
。App
,一个二进制应用程序,需要在运行时的某个时刻加载libfoo
。 App
不知道在哪里找libbar
,但知道libfoo
知道。我想要完成的是在libfoo
中使用init函数,它只会将App
的当前工作目录更改为libbar
所在的位置,以最终解决所有依赖关系并使每个人高兴。
libfoo
最终需要调用libbar
中的内容,而不是在此init函数中。我不认为创建存根会起作用,因为符号最终需要解析为真正的函数。
答案 0 :(得分:4)
即使使用RTLD_LAZY
,变量仍然可以解析,因此通常需要链接所有库。看起来你应该创建一个没有功能的链接libbar.so.1
,链接器可以找到它。
答案 1 :(得分:0)
只是想一想,您是否想过插入依赖关系 - 只需创建一个具有相同签名,参数等的相同函数,让链接器解析此函数并忽略libbar.so.1?既然你没有提到这个,我想我会建议这个。
希望这有帮助, 最好的祝福, 汤姆。
答案 2 :(得分:0)
另一个想法:将libfoo.so.1
中的必要函数(使用ar(1))提取到.o
或另一个.so
文件中,然后链接到提取帮助?我假设libbar.so.1
的引用位于libfoo函数中,该函数未从程序中调用(甚至间接)。
答案 3 :(得分:0)
这里的实际要求是什么?仅仅链接图书馆并没有太大作用,而且通常是良性的。你缺少图书馆吗?只需创建一个同名的存根库。您想控制或抢占库中符号的使用吗?把它们放在另一个库中(使用正确的版本标签!)和LD_PRELOAD吧。
我想这里的元问题是我没有看到能够抢占依赖关系的价值。它只是一个辅助功能。
答案 4 :(得分:-1)
使用dlopen加载库和dlsym以获得所需的功能。