1. 程式人生 > >如何讀取動態連結庫中的符號表,並呼叫

如何讀取動態連結庫中的符號表,並呼叫

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()函式中,引數flag的值必須是RTLD_LAZY或者RTLD_NOW,RTLD_LAZY的意思是resolv e undefined symbols as code from the dynamic library is executed,而RTLD_NOW的含 義是resolve all undefined symbols before dlopen() returns and fail if this canno t be done'。 

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

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



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

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

如果你載入了一個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) 



/* handle error, the symbol wasn't found */ 



else 



/* symbol found, its value is in s */