当两个共享库依赖于以不同方式编译的第三方的相同版本时该怎么办?

时间:2011-04-06 12:04:44

标签: c++ linux shared-libraries

我的应用程序依赖于某个版本的xerces(使用特定标志编译):

$ ldd actimize_intelligence_server | grep xerces
    libxerces-c.so.28 => ./libxerces-c.so.28 (0x00002b3c1518f000)

共享库(从客户端接收)也依赖于xerces(显然使用不同的标志编译):

$ ldd libgqt.so | grep xerces
    libxerces-c.so.28 => ./bin/libxerces-c.so.28 (0x00002b1f3d28f000)

尝试启动应用程序会出现此错误:

symbol lookup error: libgqt.so: undefined symbol: _ZN11xercesc_2_825DOMImplementationRegistry20getDOMImplementationEPKt

缺少的符号是:

  

xercesc_2_8 :: DOMImplementationRegistry :: getDOMImplementation(unsigned short const *)

虽然我的libxerces-c.so.28中的导出符号是:

  

xercesc_2_8 :: DOMImplementationRegistry :: getDOMImplementation(wchar_t const *)

所以我猜这就是问题所在。启动应用程序时运行strace显示正在加载我的libxerces-c.so.28

open("/home/test/app/libxerces-c.so.28", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\365\31\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0555, st_size=5757256, ...}) = 0
mmap(NULL, 6791128, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2ba744950000
mprotect(0x2ba744e82000, 1044480, PROT_NONE) = 0
mmap(0x2ba744f81000, 299008, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x531000) = 0x2ba744f81000
close(3)

不再出现libxerces-c.so.28

在这里,我对Linux的一点知识就此结束了。

我可以以某种方式强制其他libxerces-c.so.28加载,即使它已经加载了吗? 如果没有,除了告诉我的客户他需要重新编译他的代码以使其与我们的xerces一起工作之外,我还有其他选择吗?

2 个答案:

答案 0 :(得分:3)

你完全不能这样做。不要乱用像这样的二进制兼容性 - 如果你想动态链接到同一个库,它必须以相同的方式编译。

答案 1 :(得分:1)

您没有说出您需要libgqt.so的内容,以及您的申请取决于它的程度。

如果你真的不依赖libgqt.so,只是使用其中的一些符号为特定客户做某事,那么dlmopen(LM_ID_NEWLM, "libgqt.so", RTLD_NOW)可能是可行解决方案文档here

一般来说,DeadMG是正确的:你最好的办法是确保使用完全相同的xerces编译,否则你迟早会受伤。

请注意,静态链接xerces到您的应用程序是不太可行的。事情似乎有效,只会在不可预测的时间崩溃。