2013-02-04 22 views
0

我目前在Linux上與兩個第三方共享庫(A.so和B.so)鏈接。問題是兩者都與另一個庫靜態鏈接,因此A.so和B.so中有大約400個函數具有相同的名稱。 當我編譯並鏈接-lA -lB或-lB -lA時,根據順序,函數從A或B中分別作爲導致問題並導致代碼無法運行的函數中斷的結果。我想知道是否有一種方法可以將函數名綁定到它們的庫,這樣兩個庫可以被鏈接和使用?因爲那些重疊的函數名稱在A和B內部被內部調用,所以我不能使用objcopy等東西會對dlopen有幫助嗎?如何鏈接兩個具有許多衝突函數的共享庫

+0

問:你可以從C.a中提取所有東西,並將它變成一個共享庫嗎? – paulsm4

+0

@ paulsm4你確定能解決問題嗎? – us2012

回答

4

我想知道是否有一種方法將函數名綁定到它們的庫中,這樣兩個庫都可以被鏈接和使用?

當兩個庫有聯繫,他們應該控制其出口的符號,並且應該隱藏在「其他」的庫,但他們沒有...

將dlopen的幫助?

是:如果你dlopen("A.so", RTLD_LOCAL);dlopen("B.so", RTLD_LOCAL);,則兩個庫將被添加到全球範圍內,他們不會「看到」對方。

您必須從A.soB.so明確查找所需的符號,但這是您可以做的最好的。

更新:

是有一個快速的方法來鏈接到靜態庫,而不從「其他」庫中導出的符號,同時建立A.so

這是最好的做在應該輸出的符號上使用-fvisibility=hidden標誌和__attribute__((visibility("default")))。例如:

#define EXPORTED __attribute__((visibility("default"))) 

struct Foo { 
    void EXPORTED ExportedFunction(); 
    void EXPORTED AnotherExportedFunction(); 
    void InternalFunction(); 
}; 

void Foo::ExportedFunction() { } 
void Foo::AnotherExportedFunction() { } 
void Foo::InternalFunction() { } 


gcc -shared -fPIC -o foo.so foo.cc 
nm -CD foo.so | grep Foo:: 
00000000000005fc T Foo::ExportedFunction() 
0000000000000610 T Foo::InternalFunction() 
0000000000000606 T Foo::AnotherExportedFunction() 

沒有明確的出口管制,一切都被出口(包括InternalFunction我們不希望)。

gcc -shared -fPIC -o foo.so foo.cc -fvisibility=hidden 
nm -CD foo.so | grep Foo:: 
00000000000005bc T Foo::ExportedFunction() 
00000000000005c6 T Foo::AnotherExportedFunction() 

Voilà:只有我們明確想要導出的東西是。

+0

感謝您的評論。剛剛意識到一個問題,對於第三方庫,我需要繼承它們的類,在這種情況下是否仍然可以使用dlopen?第三方庫的開發者願意合作,但他們不知道如何隱藏他們使用的「其他」靜態庫,有沒有一種快速的方法來做到這一點?像gcc中的一些標誌? – Daniel

+0

更具體地說,爲了幫助他們,有沒有一種快速鏈接到靜態庫的方法,而無需在構建A.so和B.so時從該「其他」庫中導出符號?他們願意做出更改,只要它很快.. – Daniel

+0

@Daniel我已經添加了一個示例。 –