簡體   English   中英

鏈接庫的多個版本

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM