[英]Linking with multiple versions of a library
我有一個應用程序靜態鏈接來自第三方供應商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,兩個從不混合?
感謝所有的回復。 我有一個似乎有效的解決方案。 這是一個例子的詳細問題。
在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
現在,共享庫中的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工具鏈做了類似的事情,其中動態庫不是復雜的,但是同一個lib的兩個版本需要干凈地鏈接到一個整體應用程序。
抱歉,沒有。 我對Linux(以及可能是大多數* nixes)的方式的理解是不可能的。 我能想到的唯一“解決方案”就是你創建一個代理應用程序,它以某種IPC的形式從libbar中公開你所需要的東西。 然后,您可以使用LD_LIBRARY_PATH
或類似的東西使該代理加載正確的版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.