Yer*_*ues 31 c c++ unix linux linker
我有一个应用程序静态链接来自第三方供应商VENDOR1的库libfoo的X版本.它还与来自不同第三方供应商VENDOR2的动态(共享)库libbar链接,该库将libfoo的Y版本与VENDOR1静态链接.
因此libbar.so包含libfoo.a的版本Y,我的可执行文件包含libfoo.a的版本X.libbar仅在内部使用libfoo,并且没有从我的应用程序传递到libbar的libfoo对象.
构建时没有错误,但在运行时app app出现故障.原因似乎是版本X使用具有不同的尺寸,他们的版本Y和运行时链接似乎混合了结构,它们习惯于通过.
VENDOR1和VENDOR2都是封闭源,所以我无法重建它们.
是否有建立/链接我的应用程序,使得它始终解析版本X和libbar的送花儿给人解析到版本Y和两个从未混合的方法吗?
Yer*_*ues 16
感谢所有的回复.我有一个似乎有效的解决方案.这是一个例子的详细问题.
在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());
}
Run Code Online (Sandbox Code Playgroud)
在foo.c中我们有:
extern int bar();
int foo()
{
int x = bar();
return x;
}
Run Code Online (Sandbox Code Playgroud)
在bar.c我们有:
#include <stdio.h>
int bar()
{
printf("bar in bar.c called\n");
return 2;
}
Run Code Online (Sandbox Code Playgroud)
编译bar.c和foo.c:
$ gcc -fPIC -c bar.c
$ gcc -fPIC -c foo.c
Run Code Online (Sandbox Code Playgroud)
将bar.o添加到静态库:
$ ar r libbar.a bar.o
Run Code Online (Sandbox Code Playgroud)
现在使用foo.o创建一个共享库,并使用静态libbar.a进行链接
$ gcc -shared -o libfoo.so foo.o -L. -lbar
Run Code Online (Sandbox Code Playgroud)
编译main.c并链接共享库libfoo.so
$ gcc -o main main.c -L. -lfoo
Run Code Online (Sandbox Code Playgroud)
设置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
Run Code Online (Sandbox Code Playgroud)
请注意,调用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());
}
Run Code Online (Sandbox Code Playgroud)
编译并运行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
Run Code Online (Sandbox Code Playgroud)
现在,共享库中的foo调用了main.c中的共享库和主调用栏
我不认为这种行为是直观的,使用dlopen/dlsym是更多的工作,但它确实解决了我的问题.
再次感谢您的评论.
尝试使用部分链接,以便使用libbar和libfoo-Y创建一个目标文件"partial.o".使用带有"--localize-symbols"的objcopy在libfoo-Y local中创建partial.o中的符号.您应该能够通过在libfoo-Y上运行nm并按摩输出来生成.然后获取修改后的partial.o并将其链接到您的应用程序.
我在vxWorks上用gcc工具链做了类似的事情,其中动态库不是复杂的,但需要两个版本的同一个库才能干净地链接到一个单片应用程序.