2011-06-06 103 views
2

我有一個靜態和動態鏈接到同一個庫的共享對象/可執行文件。靜態和動態鏈接Linux上的同一個庫

庫:liba.a和liba.so

liba.a使用創建的:AR -rv liba.a AO, 包含libprint() - >打印「static5 「

liba.so使用創建的:GCC -shared -o liba.so -Wl,-h,liba.so AO,包含libprint()打印 」dynamic5「 libprint2()打印 「dynamic6」

埃克b通過鏈接到兩個歸檔創建和共享對象:

當與GCC/Linux的連接,我發現,稱爲實施始終來自liba.a。

我有一個函數libprint()定義在liba.so中,liba.a打印出一個不同的值。 從我看到的,這是基於連接順序:

GCC -Ob博liba.a liba.so -lc ./b

static5 dynamic6

GCC -Ob博liba.so liba.a -lc ./b

dynamic5 dynamic6

爲什麼我們故意需要鏈接到同一個庫的.a和.so:

我們如何讓共享對象優先於歸檔而不是鏈接順序? (-dy/-Bdynamic似乎並沒有產生什麼影響?)

1.如果共享對象丟失,這個exe因錯誤而失敗 2.我們可以放置任何具有相同名稱的虛擬共享對象,只是爲了滿足dlopen() 3。即使一旦共享對象被加載,從歸檔的函數被調用

更新#2 這裏是(如在Statically and dynamically linking the same library提到的)的實際問題

libd.so鏈接到共享對象liba.so
ldd libd.so liba.so => ./liba.so

b被鏈接到共享對象libd.so和歸檔liba.a

GCC -ob博libd.so liba.a -lc LDD b libd.so => ./libd.so liba.so => ./liba.so

現在,b似乎首先從存檔調用函數,然後是共享對象。

所以,即使我們更新liba.so,這些變化不會反映在b。 有沒有辦法解決這個問題?

+0

可能要添加/搜索標籤gcc。祝你好運。 – shellter 2011-06-06 03:28:20

回答

1

當您首先插入.a時,鏈接器會在其中找到libprint()並鏈接它,但不鏈接到libprint2()。它繼續搜索庫以查找其他函數,並在.so中找到它。

當你把.so放到第一位時,兩個函數都被找到併成功鏈接,因此不需要再進一步查找它們。

應該沒有理由鏈接兩個同一個庫的靜態和動態版本,因爲任一個都應該提供在另一個庫中找到的所有函數。

+0

謝謝@ ignacio-vazquez-abrams。 我有一個鏈接到.a和.so的可執行文件。我試圖找出可能的原因。 問題是,我們可以更新共享對象,但它似乎沒有被調用,因爲可執行文件仍然使用原始存檔中的函數。 – TTA 2011-06-06 07:10:24

+0

.a文件[在構建時鏈接](http://stackoverflow.com/questions/2246799/static-library-dynamic-library-confusion/2246911#2246911)。 – 2011-06-06 07:17:43

+0

我已更新與實際案件的問題。 共享目標文件首先在鏈接行中,但是,實際功能存在於鏈接的so文件中,而不是實際的。 這仍然會導致存檔版本被拿起。 – TTA 2011-06-06 08:15:46