linux靜態庫 共享庫 動態庫三種庫的建立和使用

2021-06-07 07:34:06 字數 2610 閱讀 7788

參見文章

1.靜態庫

靜態庫就是一些目標檔案的集合,以.a結尾。靜態庫在程式鏈結的時候使用,鏈結器會將程式中使用 到函式的**從庫檔案中拷貝到應用程式中。一旦鏈結完成,在執行程式的時候就不需要靜態庫了。 

gcc -c libhello -o libhello.o

ar rcs libhello.a libhello.o

鏈結靜態庫
gcc -c test.c -o test.o

gcc test.o -l. -lhello -o test

2.共享庫

共享庫以.so結尾. (so == share object) 在程式的鏈結時候並不像靜態庫那樣在拷貝使用函式的**,而只是作些標記。然後在程式開始啟動執行的時候,動態地載入所需模組。

(1) 在所有基於gnu glibc的系統(當然包括linux)中,在啟動乙個elf二進位制執行程式時, 乙個特殊的程式"程式裝載器"會被自動裝載並執行。在linux中,這個程式裝載器就是    /lib/ld-linux.so.x(x是版本號)。它會查詢並裝載應用程式所依賴的所有共享庫。 被搜尋的目錄儲存在/etc/ls.so.conf檔案中,但一般/usr/local/lib並不在搜尋之列。

(2) 當然你也可以通過設定環境變數ld_library_path來設定ld的裝載路徑。這樣裝載器就會 首先搜尋該變數的目錄,然後才是預設目錄。但是記住,ld_library_path是用於開發和測試的,你可以將一些用於測試的替代共享庫的目錄放到該變數中,類似於/etc/ld.so.preload的作用。

但是該變數不應該用於正常使用者的正常程式。

(3) 如果你不使用ld_library_path環境變數,可以通過如下方式給裝載器傳入路徑:

$ /lib/ld-linux.so.2 --library-path path executable

gcc -fpic -g -c -wall a.c

gcc -fpic -g -c -wall b.c

gcc -shared -wl,-soname, libmyab.so.1 -o libmyab.so.1.0.1 a.o b.o -lpthread

一旦你建立好共享庫後就需要安裝使用了,最簡單的辦法是將庫拷貝到預設目錄下(/usr/lib)。 然後建立一些符號鏈結,最簡單的方式還是使用ldconfig(8)來處理這裡符號鏈結。最後是重新 編譯鏈結你的程式,通過-l和-l引數指定庫路徑就可以了。

3.動態載入庫

動態載入庫(dynamically loaded (dl) libraries)是指在程式執行過程中可以載入的函式庫。

而不是像共享庫一樣在程式啟動的時候載入。dl對於實現外掛程式和模組非常有用,因為他們可以讓程式

在允許時等待外掛程式的載入。在linux中,動態庫的檔案格式跟共享庫沒有區別,主要區別在於共享庫是執行時載入。

有專門的一組api用於完成開啟動態庫,查詢符號,

處理出錯,關閉動態庫等功能。

下面對這些介面函式逐一介紹:

(1) dlopen   

函式原型:void *dlopen(const char *libname,int flag);

功能描述:dlopen必須在dlerror,dlsym和dlclose之前呼叫,表示要將庫裝載到記憶體,準備使用。

如果要裝載的庫依賴於其它庫,必須首先裝載依賴庫。如果dlopen操作失敗,返回null值;如果庫已經

被裝載過,則dlopen會返回同樣的控制代碼。

引數中的libname一般是庫的全路徑,這樣dlopen會直接裝載該檔案;如果只是指定了庫名稱,在dlopen

會按照下面的機制去搜尋:

a.根據環境變數ld_library_path查詢

b.根據/etc/ld.so.cache查詢

c.查詢依次在/lib和/usr/lib目錄查詢。

flag引數表示處理未定義函式的方式,可以使用rtld_lazy或rtld_now。rtld_lazy表示暫時不去

處理未定義函式,先把庫裝載到記憶體,等用到沒定義的函式再說;rtld_now表示馬上檢查是否存在未定義

的函式,若存在,則dlopen以失敗告終。

(2) dlerror

函式原型:char *dlerror(void);

功能描述:dlerror可以獲得最近一次dlopen,dlsym或dlclose操作的錯誤資訊,返回null表示

無錯誤。dlerror在返回錯誤資訊的同時,也會清除錯誤資訊。

(3) dlsym

函式原型:void *dlsym(void *handle,const char *symbol);

功能描述:在dlopen之後,庫被裝載到記憶體。dlsym可以獲得指定函式(symbol)在記憶體中的位置(指標)。

如果找不到指定函式,則dlsym會返回null值。但判斷函式是否存在最好的方法是使用dlerror函式,

(4) dlclose

函式原型:int dlclose(void *);

功能描述:將已經裝載的庫控制代碼減一,如果控制代碼減至零,則該庫會被解除安裝。如果存在析構函式,則在dlclose

之後,析構函式會被呼叫。   

使用動態庫

gcc -o dltest dltest.c -ldl -wall

Linux 靜態庫與動態(共享)庫

不論是在linux還是windows下程式設計,我們都會用到庫,有自身帶的標準庫,也有我們自己寫的庫,庫就是預先編譯好的的方法的集合。linux中的庫可以分為兩種,靜態庫和動態庫,動態庫也稱為共享庫。在linux中,庫名稱都以lib開始,靜態庫名為 lib a,動態庫名為 lib so。靜態庫和動態...

靜態庫,共享庫,動態載入庫

一 靜態庫 1.概念 靜態庫就是一些目標檔案的集合,以.a結尾。靜態庫在程式鏈結的時候使用,鏈結器會將程式中使用 到函式的 從庫檔案中拷貝到應用程式中。一旦鏈結完成,在執行程式的時候就不需要靜態庫了。由於每個使用靜態庫的應用程式都需要拷貝所用函式的 所以靜態鏈結的檔案會比較大。2.建立與應用 首先建...

Linux 靜態庫 共享庫 動態庫 讀書筆記

靜態函式庫是在程式執行前就加入到目標程式中去了 而共享函式庫則是在程式啟動的時候載入到程式中,它可以被不同的程式共享 動態載入函式庫則可以在程式執行的任何時候動態的載入。靜態函式庫實際上就是簡單的乙個普通的目標檔案的集合,一般來說習慣用 a 作為檔案的字尾。可以用ar這個程式來產生靜態函式庫檔案。靜...