Linux動態鏈結庫的建立與使用

2021-04-21 12:23:56 字數 2506 閱讀 3541

使用gnu的工具我們如何在linux下建立自己的程式函式庫?乙個「程式函式庫」簡單的說就是乙個檔案包含了一些編譯好的**和資料,這些編譯好的**和資料可以在事後供其他的程式使用。程式函式庫可以使整個程式更加模組化,更容易重新編譯,而且更方便公升級。

libc.so.n(n應該大於或者等於6)。這是c語言函式庫。

動態載入的函式庫dynamically loaded (dl) libraries是一類函式庫,它可以在程式執行過程中的任何時間載入。它們特別適合在函式中載入一些模組和plugin擴充套件模組的場合,因為它可以在當程式需要某個plugin模組時才動態的載入。例如,pluggable authentication modules(pam)系統就是用動態載入函式庫來使得管理員可以配置和重新配置身份驗證資訊。

linux系統下,dl函式庫與其他函式庫在格式上沒有特殊的區別,我們前面提到過,它們建立的時候是標準的object格式。主要的區別就是這些函式庫不是在程式鏈結的時候或者啟動的時候載入,而是通過乙個api來開啟乙個函式庫,尋找符號表,處理錯誤和關閉函式庫。通常c語言環境下,需要包含這個標頭檔案。 

http://developer.gnome.org/doc/api/glib/glib-dynamic-loading-of-modules.html. 另外乙個方法是使用libltdl,是gnu libtool的一部分,可以進一步參考corba相關資料。  

dlopen函式開啟乙個函式庫然後為後面的使用做準備。c語言原形是:

void * dlopen(const char *filename, int flag);

如果檔名filename是以「/」開頭,也就是使用絕對路徑,那麼dlopne就直接使用它,而不去查詢某些環境變數或者系統設定的函式庫所在的目錄了。否則dlopen()就會按照下面的次序查詢函式庫檔案:

1. 環境變數ld_library指明的路徑。

2. /etc/ld.so.cache中的函式庫列表。

3. /lib目錄,然後/usr/lib。不過一些很老的a.out的loader則是採用相反的次序,也就是先查 /usr/lib,然後是/lib。

dlopen()函式中,

如果有好幾個函式庫,它們之間有一些依賴關係的話,例如x依賴y,那麼你就要先載入那些被依賴的函式。例如先載入y,然後載入x。

dlopen()函式的返回值是乙個控制代碼,然後後面的函式就通過使用這個控制代碼來做進一步的操作。如果開啟失敗dlopen()就返回乙個null。如果乙個函式庫被多次開啟,它會返回同樣的控制代碼。 

如果乙個函式庫裡面有乙個輸出的函式名字為_init,那麼_init就會在dlopen()這個函式返回前被執行。我們可以利用這個函式在我的函式庫裡面做一些初始化的工作。我們後面會繼續討論這個問題的。  

通過呼叫dlerror()函式,我們可以獲得最後一次呼叫dlopen(),dlsym(),或者dlclose()的錯誤資訊。 

如果你載入了乙個dl函式庫而不去使用當然是不可能的了,使用乙個dl函式庫的最主要的乙個函式就是dlsym(),這個函式在乙個已經開啟的函式庫裡面查詢給定的符號。這個函式如下定義:

void * dlsym(void *handle, char *symbol);

函式中的引數handle就是由dlopen開啟後返回的控制代碼,symbol是乙個以nil結尾的字串。如果dlsym()函式沒有找到需要查詢的symbol,則返回null。如果你知道某個symbol的值不可能是null或者0,那麼就很好,你就可以根據這個返回結果判斷查詢的symbol是否存在了;不過,如果某個symbol的值就是null,那麼這個判斷就有問題了。標準的判斷方法是先呼叫dlerror(),清除以前可能存在的錯誤,然後呼叫dlsym()來訪問乙個symbol,然後再呼叫dlerror()來判斷是否出現了錯誤。乙個典型的過程如下:

dlerror(); /* clear error code */

s = (actual_type) dlsym(handle, symbol_being_searched_for);

if ((err = dlerror()) != null)

else

dlopen()函式的反過程就是dlclose()函式,dlclose()函式用力關閉乙個dl函式庫。dl函式庫維持乙個資源利用的計數器,當呼叫dlclose的時候,就把這個計數器的計數減一,如果計數器為0,則真正的釋放掉。真正釋放的時候,如果函式庫裡面有_fini()這個函式,則自動呼叫_fini()這個函式,做一些必要的處理。dlclose()返回0表示成功,其他非0值表示錯誤。

下面是乙個例子。例子中調入math函式庫,然後列印2.0的余弦函式值。例子中每次都檢查是否出錯。應該是個不錯的範例:

int main(int argc, char **argv)

cosine = dlsym(handle, "cos");

if ((error = dlerror()) != null)

printf ("%f ", (*cosine)(2.0));

dlclose(handle);

}

如果這個程式名字叫foo.c,那麼用下面的命令來編譯:

gcc -o foo foo.c -ldl

解析Linux靜態與動態鏈結庫的建立和使用

首先由下面幾個函式 strlen.h strlen.c strnlen.c main.c strlen.h 標頭檔案int strnlen char pstr,unsigned long ulmaxlen int strlen char pstr strlen.c 實現給定字串的長度 include...

linux動態鏈結庫的建立與使用

建立linux動態鏈結庫 從void dlsym void handle,char symbol 的引數可以看出,該函式只傳兩個引數 乙個指向so的handle和乙個函式的symbol,所以so裡面的函式應該不允許過載,否則根據乙個symbol不能確定指向那個函式。為了相容c和c 在so中定義函式時...

建立靜態鏈結庫 動態鏈結庫

下面的實操中的動態庫或者靜態庫名都用wujunwu 第一步 建立乙個源 建立靜態鏈結庫的源 include void func1 void int func2 int x,int y 第二步 建立乙個.件作為函式宣告 void func1 void intfunc2 int x,int y 第三步 ...