dlopen、dlsym和dlclose的使用和舉例.docx_第1頁(yè)
dlopen、dlsym和dlclose的使用和舉例.docx_第2頁(yè)
dlopen、dlsym和dlclose的使用和舉例.docx_第3頁(yè)
dlopen、dlsym和dlclose的使用和舉例.docx_第4頁(yè)
dlopen、dlsym和dlclose的使用和舉例.docx_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

dlopen、dlsym和dlclose的使用和舉例 之前用過(guò)這三個(gè)函數(shù)一直沒(méi)時(shí)間整理一下。今天抽時(shí)間整理一下。1、函數(shù)簡(jiǎn)介dlopen基本定義功能:打開(kāi)一個(gè)動(dòng)態(tài)鏈接庫(kù)包含頭文件:#include 函數(shù)定義:void * dlopen( const char * pathname, int mode );函數(shù)描述:在dlopen的()函數(shù)以指定模式打開(kāi)指定的動(dòng)態(tài)連接庫(kù)文件,并返回一個(gè)句柄給調(diào)用進(jìn)程。使用dlclose()來(lái)卸載打開(kāi)的庫(kù)。mode:分為這兩種RTLD_LAZY暫緩決定,等有需要時(shí)再解出符號(hào)RTLD_NOW立即決定,返回前解除所有未決定的符號(hào)。RTLD_LOCALRTLD_GLOBAL允許導(dǎo)出符號(hào)RTLD_GROUPRTLD_WORLD返回值:打開(kāi)錯(cuò)誤返回NULL成功,返回庫(kù)引用編譯時(shí)候要加入-ldl (指定dl庫(kù))dlsym()功能:根據(jù)動(dòng)態(tài)鏈接庫(kù)操作句柄與符號(hào),返回符號(hào)對(duì)應(yīng)的地址。包含頭文件:#include 函數(shù)定義:void*dlsym(void* handle,const char* symbol)函數(shù)描述:dlsym根據(jù)動(dòng)態(tài)鏈接庫(kù)操作句柄(handle)與符號(hào)(symbol),返回符號(hào)對(duì)應(yīng)的地址。使用這個(gè)函數(shù)不但可以獲取函數(shù)地址,也可以獲取變量地址。handle是由dlopen打開(kāi)動(dòng)態(tài)鏈接庫(kù)后返回的指針,symbol就是要求獲取的函數(shù)或全局變量的名稱。dlclose()dlclose用于關(guān)閉指定句柄的動(dòng)態(tài)鏈接庫(kù),只有當(dāng)此動(dòng)態(tài)鏈接庫(kù)的使用計(jì)數(shù)為0時(shí),才會(huì)真正被系統(tǒng)卸載。上述都是摘抄,總結(jié)為鏈接的時(shí)候需要用到dl庫(kù),編譯的時(shí)候需要加上dlfcn.h頭文件。才能保證編譯不會(huì)報(bào)錯(cuò)。2、生成動(dòng)態(tài)庫(kù)hello.c函數(shù)原型:#include #include #include #include typedef struct const char*module;int (*GetValue)(char *pszVal);int (*PrintfHello)(); hello_ST_API;int GetValue(char *pszVal)int retval = -1;if (pszVal)retval = sprintf(pszVal, %s, 123456);printf(%s, %d, pszVer = %sn, _FUNCTION_, _LINE_, pszVal);return retval;int PrintfHello()int retval = -1;printf(%s, %d, hello everyonen, _FUNCTION_, _LINE_);return 0;const hello_ST_API Hello = .module= hello, GetValue, PrintfHello,;編譯的時(shí)候用指令:gcc -shared -o hello.so hello.c上面的函數(shù)是用一個(gè)全局結(jié)構(gòu)體hello來(lái)指向。在dlsym定義中說(shuō)不僅可以獲取函數(shù)的地址,還可以獲取全局變量的地址。所以此處是想通過(guò)dlsym來(lái)獲取全局變量的地址。好處自己慢慢體會(huì)。3、dlopen代碼#include #include #include #include #include typedef struct const char*module;int (*GetValue)(char *pszVal);int (*PrintfHello)(); hello_ST_API;int main(int argc, char *argv)hello_ST_API *hello;int i = 0;void *handle;char psValue20 = 0;handle = dlopen(“庫(kù)存放的絕對(duì)路徑,你可以試試相對(duì)路徑是不行的, RTLD_LAZY);if (! handle) printf(%s,%d, NULL = handlen, _FUNCTION_, _LINE_);return -1;dlerror();hello = dlsym(handle, Hello);if (!hello) printf(%s,%d, NULL = handlen, _FUNCTION_, _LINE_);return -1;if (hello & hello-PrintfHello)i = hello-PrintfHello();printf(%s, %d, i = %dn, _FUNCTION_, _LINE_, i);if (hello & hello-GetValue)i = hello-GetValue(psValue);if (hello & hello-module)printf(%s, %d, module = %sn, _FUNCTION_, _LINE_, hello-module); dlclose(handle); return 0;編譯指令:gcc -otest hello_dlopen.c -ldl運(yùn)行./test結(jié)果如下。PrintfHello, 27, hello everyonemain, 36, i = 0GetValue, 19, pszVer = 123456main, 42, module = hello可以看到結(jié)果正常出來(lái)了??吹?jīng)]用?dlsym找到全局結(jié)構(gòu)體hello后,可以直接用這個(gè)全局結(jié)構(gòu)體指針來(lái)使用庫(kù)里面的函數(shù)了,因?yàn)槲覀冇袝r(shí)候提供的庫(kù)不僅僅是一個(gè)兩個(gè)函數(shù)的,一般的一個(gè)庫(kù)都會(huì)存在多個(gè)函數(shù),用這種方式就可以直接使用了。不然找函數(shù)名稱的話要寫(xiě)多少個(gè)dlsym???dlopen,dlsym打開(kāi)動(dòng)態(tài)庫(kù),并裝入內(nèi)存除了傳統(tǒng)的包含頭文件.h文件可以調(diào)用函數(shù)外,還有很好的辦法便是這個(gè),加載動(dòng)態(tài)庫(kù)函數(shù)句柄,如函數(shù)名為fun(int a,char b),則加載為fun.功能:打開(kāi)一個(gè)動(dòng)態(tài)鏈接庫(kù)包含頭文件:#include 函數(shù)定義:void * dlopen( const char *pathname, intmode);dlopen()是一個(gè)強(qiáng)大的庫(kù)函數(shù)。該函數(shù)將打開(kāi)一個(gè)新庫(kù),并把它裝入內(nèi)存。該函數(shù)主要用來(lái)加載庫(kù)中的符號(hào),這些符號(hào)在編譯的時(shí)候是不知道的。比如 Apache Web 服務(wù)器利用這個(gè)函數(shù)在運(yùn)行過(guò)程中加載模塊,這為它提供了額外的能力。一個(gè)配置文件控制了加載模塊的過(guò)程。這種機(jī)制使得在系統(tǒng)中添加或者刪除一個(gè)模塊時(shí),都不需要重新編譯了??梢栽谧约旱某绦蛑惺褂?dlopen()。dlopen() 在 dlfcn.h 中定義,并在 dl 庫(kù)中實(shí)現(xiàn)。它需要兩個(gè)參數(shù):一個(gè)文件名和一個(gè)標(biāo)志。文件名可以是我們學(xué)習(xí)過(guò)的庫(kù)中的 soname。標(biāo)志指明是否立刻計(jì)算庫(kù)的依賴性。如果設(shè)置為 RTLD_NOW 的話,則立刻計(jì)算;如果設(shè)置的是 RTLD_LAZY,則在需要的時(shí)候才計(jì)算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加載的庫(kù)可以獲得其中的符號(hào)。當(dāng)庫(kù)被裝入后,可以把 dlopen() 返回的句柄作為給 dlsym() 的第一個(gè)參數(shù),以獲得符號(hào)在庫(kù)中的地址。使用這個(gè)地址,就可以獲得庫(kù)中特定函數(shù)的指針,并且調(diào)用裝載庫(kù)中的相應(yīng)函數(shù)。dlsym()的函數(shù)原型是void* dlsym(void* handle,const char* symbol)該函數(shù)在文件中。handle是由dlopen打開(kāi)動(dòng)態(tài)鏈接庫(kù)后返回的指針,symbol就是要求獲取的函數(shù)的名稱,函數(shù)返回值是void*,指向函數(shù)的地址,供調(diào)用使用例程#include #include #include intmain(int argc, char *argv)void *handle;double (*cosine)(double);char *error;handle = dlopen(libm.so, RTLD_LAZY);if (!handle) fprintf(stderr, %sn, dlerror();exit(EXIT_FAILURE);dlerror(); *(voi

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論