dlopen & dlsys 動態加載庫

在讀HAL相關源碼的時候發現這兩個函數  html

簡而言之,共享對象經過dlopen動態打開動態庫的加載完成後,返回一個句柄,經過dlsym定位到你須要執行的函數指針而後能夠在程序中使用 服務器

 

dlopen -- open a dynamically linked library 函數

 

dlsym -- get the address of a symbol in a dynamically linked library 學習

 

例子void *handle; spa

     int i, *iptr; .net

     int (*fptr)(int); 3d

     /* open the needed object */ 指針

     handle = dlopen("/usr/mydir/libx.so", RTLD_LAZY); htm

 

     /* find address of function and data objects */ 對象

     fptr = (int (*)(int))dlsym(handle, "some_function");

 

     iptr = (int *)dlsym(handle, "int_object");

 

     /* invoke function, passing value of integer as a parameter */

 

     i = (*fptr)(*iptr);

 

 

參考資料http://topic.csdn.net/u/20090422/17/2ddcab88-2d50-478a-9b2e-2c2978ad604b.html

http://hi.baidu.com/janefei1603/blog/item/72ae708eed638eda503d923b.html

Additional link: http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html

 

 

具體實現

 

dlopen

基本定義

功能:打開一個動態連接庫 
  包含頭文件: 
  #include <dlfcn.h> 
  函數定義: 
  void * dlopen( const char * pathname, int mode ); 
  函數描述: 
  在dlopen的()函數以指定模式打開指定的動態鏈接庫文件,並返回一個句柄給調用進程。使用dlclose()來卸載打開的庫。 
  mode:分爲這兩種 
  RTLD_LAZY 暫緩決定,等有須要時再解出符號 
  RTLD_NOW 當即決定,返回前解除全部未決定的符號。 
  RTLD_LOCAL 
  RTLD_GLOBAL 容許導出符號 
  RTLD_GROUP 


  RTLD_WORLD 
  返回值
  打開錯誤返回NULL 
  成功,返回庫引用 
  編譯時候要加入 -ldl (指定dl
  例如 
  gcc test.c -o test -ldl
編輯本段
使用 dlopen
  dlopen()是一個強大的庫函數。該函數將打開一個新庫,並把它裝入內存。該函數主要用來加載庫中的符號,這些符號在編譯的時候是不知道的。好比 Apache Web 服務器利用這個函數在運行過程當中加載模塊,這爲它提供了額外的能力。一個配置文件控制了加載模塊的過程。這種機制使得在系統中添加或者刪除一個模塊時,都不須要從新編譯了。 
  能夠在本身的程序中使用 dlopen()dlopen()  dlfcn.h 中定義,並在 dl 庫中實現。它須要兩個參數:一個文件名和一個標誌。文件名能夠是咱們學習過的庫中的 soname。標誌指明是否馬上計算庫的依賴性。若是設置爲 RTLD_NOW 的話,則馬上計算;若是設置的是 RTLD_LAZY,則在須要的時候才計算。另外,能夠指定 RTLD_GLOBAL,它使得那些在之後才加載的庫能夠得到其中的符號。 

  當庫被裝入後,能夠把 dlopen() 返回的句柄做爲給 dlsym() 的第一個參數,以得到符號在庫中的地址。使用這個地址,就能夠得到庫中特定函數的指針,而且調用裝載庫中的相應函數。

 

 

dlsym
   
  dlsym()的函數原型是 
  void* dlsym(void* handle,const char* symbol) 
  該函數在<dlfcn.h>文件中。 
  handle是由dlopen打開動態連接庫後返回的指針,symbol就是要求獲取的函數的名稱,函數返回值是void*,指向函數的地址,供調用使用

取動態對象地址:
#include <dlfcn.h>
void *dlsym(void *pHandle, char *symbol);
dlsym
根據動態連接庫操做句柄(pHandle)與符號(symbol),返回符號對應的地址。
使用這個函數不但能夠獲取函數地址,也能夠獲取變量地址。好比,假設在so
定義了一個void mytest()函數,那在使用so時先聲明一個函數指針:
void (*pMytest)(),
而後使用dlsym函數將函數指針pMytest指向mytest函數, pMytest = (void (*)())dlsym(pHandle, "mytest");

相關文章
相關標籤/搜索