Linux下動態庫使用小結

2021-09-06 09:36:35 字數 1678 閱讀 1009

1. 靜態庫和動態庫的基本概念

靜態庫,是在可執行程式連線時就已經加入到執行碼中,在物理上成為執行程式的一部分;使用靜態庫編譯的程式執行時無需該庫檔案支援,**都可以用,但是生成的可執行檔案較大。動態庫,是在可執行程式啟動時載入到執行程式中,可以被多個可執行程式共享使用。使用動態庫編譯生成的程式相對較小,但執行時需要庫檔案支援,如果機器裡沒有這些庫檔案就不能執行。

2.  如何使用動態庫

如何程式在連線時使用了共享庫,就必須在執行的時候能夠找到共享庫的位置。linux的可執行程式在執行的時候預設是先搜尋/lib和/usr/lib這兩個目錄,然後按照/etc/ld.so.conf裡面的配置搜尋絕對路徑。同時,linux也提供了環境變數ld_library_path供使用者選擇使用,使用者可以通過設定它來查詢除預設路徑之外的其他路徑,如查詢/work/lib路徑,你可以在/etc/rc.d/rc.local或其他系統啟動後即可執行到的指令碼新增如下語句:ld_library_path =/work/lib:$(ld_library_path)。並且ld_library_path路徑優先於系統預設路徑之前查詢(詳細參考《使用ld_library_path》)。

不過ld_library_path的設定作用是全域性的,過多的使用可能會影響到其他應用程式的執行,所以多用在除錯。(ld_library_path的缺陷和使用準則,可以參考《why ld_library_path is bad》 )。通常情況下推薦還是使用gcc的-r或-rpath選項來在編譯時就指定庫的查詢路徑,並且該庫的路徑資訊儲存在可執行檔案中,執行時它會直接到該路徑查詢庫,避免了使用ld_library_path環境變數查詢。

3.庫的鏈結時路徑和執行時路徑

現代聯結器在處理動態庫時將鏈結時路徑(link-time path)和執行時路徑(run-time path)分開,使用者可以通過-l指定連線時庫的路徑,通過-r(或-rpath)指定程式執行時庫的路徑,大大提高了庫應用的靈活性。比如我們做嵌入式移植時#arm-linux-gcc $(cflags) –o target  –l/work/lib/zlib/ -llibz-1.2.3  (work/lib/zlib下是交叉編譯好的zlib庫),將target編譯好後我們只要把zlib庫拷貝到開發板的系統預設路徑下即可。或者通過-rpath(或-r )、ld_library_path指定查詢路徑。

小問題:

1.編譯時的-l選項是否影響ld_library_path的值?

舉乙個例項:

當前資料夾結構如下:

test.c tools/

tool下有tool.c tool.h my_err.h 以及由此生成的libtool.so

tool下編譯生成庫檔案

gcc -wall -g -shared -o tool.so tool.c

在當前資料夾引用:

gcc -wall -g –o  test.c -ltools -ltool

編譯不報錯,但是執行載入的時候就出現cannot open shared object file。

如果將該庫檔案拷貝到/usr/lib下就沒有錯誤,正常執行。

說明編譯時的-l選項並不影響環境變數ld_library_path,-l只是指定了程式編譯連線時庫的路徑,並不影響程式執行時庫的路徑,系統還是會到預設路徑下查詢該程式所需要的庫。

Linux下動態庫使用小結

1.靜態庫和動態庫的基本概念 靜態庫,是在可執行程式連線時就已經加入到執行碼中,在物理上成為執行程式的一部分 使用靜態庫編譯的程式執行時無需該庫檔案支援,都可以用,但是生成的可執行檔案較大。動態庫,是在可執行程式啟動時載入到執行程式中,可以被多個可執行程式共享使用。使用動態庫編譯生成的程式相對較小,...

linux下動態庫的使用

動態庫的呼叫分為隱式呼叫和顯式呼叫 動態庫是由原始檔編譯而成的,與普通程式不同的是,動態庫沒有main函式,不能單獨執行,需要被呼叫才能執行。寫乙個四則運算的動態庫 calculate.h檔案 ifndef calculate h h define calculate h h 加法 int add ...

Linux下動態庫生成和使用

1.動態鏈結庫是程式執行時載入的庫,當動態鏈結庫正確安裝後,所有的程式都可以使用動態庫來執行程式。動態鏈結庫是目標檔案的集合,目標檔案在動態鏈結庫中的組織方式是按照特殊方式形成的。庫中函式和變數的位址是相對位址,不是絕對位址,其真實位址在呼叫動態庫的程式載入時形成。2.動態鏈結庫的名稱有別名 son...