linux 動態庫 靜態庫 函式覆蓋

2022-05-23 04:45:07 字數 1768 閱讀 6125

本文討論了linux動態庫  靜態庫中函式的覆蓋問題。

測試目的:

同名函式,分別打成動態庫libdync_lib.so與靜態庫libstatic_lib.a,並把libstatic_lib.a打到另乙個動態庫libapi.so中,

在可執行程式中分別連線libdync_lib.so與libapi.so,此時到底呼叫的是哪個庫中的函式?

測試結論:

不同庫中的同名函式會被覆蓋,後鏈結的庫中的同名函式會被先前庫覆蓋。

測試方法:

static_lib.h

1void print();

static_lib.cpp

1 #include 2 #include "

static_lib.h"3

4void

print()

5

dync_lib.h

1void print();

dync_lib.cpp

#include #include 

"dync_lib.h

"void

print()

api.h

void func();

api.cpp

1 #include "

static_lib.h"2

3void

func()

4

main.cpp

#include int

main()

製作libdync_lib.so動態庫

g++ dync_lib.cpp -shared -fpic -o libdync_lib.so

製作libstatic_lib.a靜態庫

g++ -c static_lib.cpp -share -fpic -o static_lib.o

ar crv libstatic_lib.a static_lib.o

製作libapi.so動態庫,其依賴靜態庫libstatic_lib.a

g++ api.cpp -shared -fpic -o libapi.so -lstatic_lib

有三種方式生成可執行程式

1、g++ main.cpp -lapi -o main

2、g++ main.cpp -lapi -ldync_lib -o main

3、g++ main.cpp -ldync_lib -lapi -o main

每種方式都能執行成功,但輸出不一樣,

1、2執行時,輸出一致:

i am static print

3執行時,輸出;

i am dync print

下面分析原因:

1、第一種方式中,main.cpp中只包含了 api.h,而api.h中並沒有定義print函式,那麼main中怎麼找到了該函式並且呼叫成功了呢?

因為,生成libapi.so時連線了libstatic_lib.a,而其中包含print,也就是說,靜態庫中的函式符號都會被打到動態庫中,所以main能找到print函式的實現,來自libstatic_lib.a。

2、後2種方式中,只是額外鏈結libdync_lib.so,但鏈結的順序不同。從結果中看,程式正常執行。

第二種方式呼叫的是libstatic_lib.a中的print函式,對比發現,第三種呼叫的是libdync_lib.so中的print。

也就是說,根據鏈結的順序,先被鏈結的庫中的符號(函式)會覆蓋後面庫中的同名符號。

linux 靜態庫 動態庫

1.概念和區別 靜態庫就是在編譯過程中一些目標檔案的集合。靜態庫在程式鏈結的時候使用,鏈結器會將程式中使用到函式的 從庫檔案中拷貝到應用程式中。一旦鏈結完成,在執行程式的時候就不需要靜態庫了。由於每個使用靜態庫的應用程式都需要拷貝所用函式的 所以靜態鏈結的檔案會比較大。相對於靜態函式庫,動態函式庫在...

linux 靜態庫 動態庫

linux支援兩種庫的型別 靜態庫和動態庫 共享庫 1.linux靜態庫和動態庫的命名規則 靜態函式庫 lib a 動態函式庫 lib so 這些庫檔案都是由 o檔案生成的 動態庫 程式執行過程中進行連線。可執行檔案 庫檔案 靜態庫 編譯時進行連線。庫檔案 的複製貼上過程。程式執行時先檢查依賴的庫檔...

Linux動態庫,靜態庫

1.庫是什麼?庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。就是將源 轉化為二進位制格式的源 相當於進行了加密,別人可以使用庫,但是看不到庫中的內容。2.靜態庫 靜態函式庫時在程式執行之前 編譯 就加入到目標程式中去了 linux中命名系統中靜態庫庫的規則 靜態庫檔名的命名方式是 l...