将两个共享库链接到一些相同的符号
我正试图链接两个不同的共享库。 这两个库定义了一些共享名称但具有不同实现的符号。 我似乎无法find一种方法来使每个图书馆都使用自己的实施。
例如,这两个库定义了一个全局函数bar()
,它们都在内部调用。 库从foo1()
调用它,而库二从foo2()
调用它。
Lib1.so:
T bar T foo1() // calls bar()
Lib2.so:
T bar T foo2() // calls bar()
如果我将我的应用程序与Lib1.so和Lib2.so连接起来,即使在调用foo2()
时也会调用Lib1.so中的bar实现。 另一方面,如果我将我的应用程序链接到Lib2.so,然后是Lib1.so,那么bar总是从Lib2.so中调用。
有没有办法让图书馆总是比其他图书馆更喜欢自己的实现?
有几种方法可以解决这个问题:
-
将
-Bsymbolic
或-Bsymbolic-functions
传递给链接器。 这具有全局性的作用:每个对可以parsing为库中的符号的全局符号(-Bsymbolic-functions
的函数types)的-Bsymbolic-functions
被parsing为该符号。 有了这个,你就失去了使用LD_PRELOAD将内部库调用置入这些符号的能力。 这些符号仍然是导出的 ,所以它们可以从库外引用。 -
使用版本脚本来标记符号为本地的图书馆,例如使用类似于:
{local: bar;};
并将--version-script=versionfile
传递给链接器。 符号不会被导出。 -
标记具有适当可见性的符号( GCC信息页面的可见性 ),将隐藏 , 内部或受保护 。 受保护的可见性符号被导出为
.protected
, 隐藏的符号不会被导出 , 内部符号不会被导出 ,您不会从库之外调用它们,甚至间接通过函数指针。
您可以使用objdump -T
来检查导出的符号。
你将不得不创build两个“包装”共享库,一个用于每个现有的库。 每个应该build立一个 – dynamic列表,只列出了一些定义一个API的非冲突的符号。 您还需要-Bsymbolic来避免任何全局组合。
使用合适的选项通过dlopen访问生成的库也可能不那么紧张。