链接到一个库的多个版本

我有一个应用程序与第三方供应商VENDOR1的库libfoo的版本X静态链接。 它还与来自不同第三方供应商VENDOR2的dynamic(共享)库libbar链接,该VENDOR2静态链接来自VENDOR1的libfoo版本Y.

因此,libbar.so包含libfoo.a的版本Y,而我的可执行文件包含libfoo.a的版本X. libbar仅在内部使用libfoo,并且没有从我的应用程序传递给libbar的libfoo对象。

在构build时没有错误,但在运行时应用程序段错误。 原因似乎是版本X使用具有不同大小的结构,它们的版本是Y,而运行时链接程序似乎正在混合使用哪个版本。

VENDOR1和VENDOR2都是封闭的源码,所以我不能重build它们。

有没有办法build立/链接我的应用程序,它总是解决版本X和libbar总是解决到版本Y和两个从来没有混合?

Solutions Collecting From Web of "链接到一个库的多个版本"

感谢所有的答复。 我有一个似乎工作的解决方案。 下面是一个例子的详细问题。

在main.c中我们有:

#include <stdio.h> extern int foo(); int bar() { printf("bar in main.c called\n"); return 0; } int main() { printf("result from foo is %d\n", foo()); printf("result from bar is %d\n", bar()); } 

在foo.c中我们有:

 extern int bar(); int foo() { int x = bar(); return x; } 

在bar.c中我们有:

 #include <stdio.h> int bar() { printf("bar in bar.c called\n"); return 2; } 

编译bar.c和foo.c:

 $ gcc -fPIC -c bar.c $ gcc -fPIC -c foo.c 

将bar.o添加到静态库:

 $ ar r libbar.a bar.o 

现在使用foo.o创建一个共享库,并与静态libbar.a链接

 $ gcc -shared -o libfoo.so foo.o -L. -lbar 

编译main.c和链接到共享库libfoo.so

 $ gcc -o main main.c -L. -lfoo 

设置LD_LIBRARY_PATH来查找libfoo.so并运行main:

 $ setenv LD_LIBRARY_PATH `pwd` $ ./main bar in main.c called result from foo is 0 bar in main.c called result from bar is 0 

注意main.c中bar的版本被调用,而不是链接到共享库的版本。

在main2.c中我们有:

 #include <stdio.h> #include <dlfcn.h> int bar() { printf("bar in main2.c called\n"); return 0; } int main() { int x; int (*foo)(); void *handle = dlopen("libfoo.so", RTLD_GLOBAL|RTLD_LAZY); foo = dlsym(handle, "foo"); printf("result from foo is %d\n", foo()); printf("result from bar is %d\n", bar()); } 

编译并运行main2.c(注意我们不需要显式链接libfoo.so):

 $ gcc -o main2 main2.c -ldl $ ./main2 bar in bar.c called result from foo is 2 bar in main2.c called result from bar is 0 

现在,共享库中的共享库调用栏以及main.c中的主要调用栏

我不认为这种行为是直观的,使用dlopen / dlsym更多的工作,但它确实解决了我的问题。

再次感谢评论。

尝试一个部分链接,以便使用libbar和libfoo-Y生成一个对象文件“partial.o”。 使用带“–localize-symbols”的objcopy来使libfoo-Y的partial.o中的符号为local。 您应该能够通过在libfoo-Y上运行nm并按摩输出来生成。 然后采取修改的partial.o并将其链接到您的应用程序。

我已经在vxWorks上用gcc工具链做了类似的事情,动态库并不是一个复杂的东西,但是同一个库的两个版本需要干净地链接到一个单一的应用程序。

抱歉,没有。 我对Linux(也可能是大多数* nixes)的方式的理解是不可能的。 对于你的问题,我唯一能想到的解决方案就是创建一个代理应用程序,它以一些IPC的形式公开你需要从libbar获得的东西。 然后你可以使用LD_LIBRARY_PATH或类似的东西来加载正确的代理。