LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror
dlopen
基本定義
功能:打開(kāi)一個(gè)動(dòng)態(tài)鏈接庫(kù)?包含頭文件:?
#include <dlfcn.h>?
函數(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_LOCAL?
RTLD_GLOBAL 允許導(dǎo)出符號(hào)?
RTLD_GROUP?
RTLD_WORLD?
返回值:?
打開(kāi)錯(cuò)誤返回NULL?
成功,返回庫(kù)引用?
編譯時(shí)候要加入 -ldl (指定dl庫(kù))?
例如?
gcc test.c -o test -ldl
編輯本段
使用 dlopen
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ù)的依賴(lài)性。如果設(shè)置為 RTLD_NOW 的話(huà),則立刻計(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ù)。
?
NOTE: 如果pathname是NULL, 則返回的是調(diào)用dlopen的模塊的庫(kù)引用(handle)。 例如: 如果我們?cè)谖覀兊腁PP里面調(diào)用dlopen去動(dòng)態(tài)load一個(gè).so, 但是pathname傳入的是NULL, 則dlopen最后返回的應(yīng)該是該APP的引用(handle)
Additional link:?http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html
--------------------------------------------------------------------------------------------------------------------------
dlsym
?
dlsym()的函數(shù)原型是?
void* dlsym(void* handle,const char* symbol)?
該函數(shù)在<dlfcn.h>文件中。?
handle是由dlopen打開(kāi)動(dòng)態(tài)鏈接庫(kù)后返回的指針,symbol就是要求獲取的函數(shù)的名稱(chēng),函數(shù)返回值是void*,指向函數(shù)的地址,供調(diào)用使用
取動(dòng)態(tài)對(duì)象地址:
#include <dlfcn.h>
void *dlsym(void *pHandle, char *symbol);
dlsym根據(jù)動(dòng)態(tài)鏈接庫(kù)操作句柄(pHandle)與符號(hào)(symbol),返回符號(hào)對(duì)應(yīng)的地址。
使用這個(gè)函數(shù)不但可以獲取函數(shù)地址,也可以獲取變量地址。比如,假設(shè)在so中
定義了一個(gè)void mytest()函數(shù),那在使用so時(shí)先聲明一個(gè)函數(shù)指針:
void (*pMytest)(),然后使用dlsym函數(shù)將函數(shù)指針pMytest指向mytest函數(shù),
pMytest = (void (*)())dlsym(pHandle, "mytest");
--------------------------------------------------------------------------------------------------------------------------
dlclose
dlclose()?
包含頭文件:?
#include <dlfcn.h>?
函數(shù)原型為:?
int dlclose (void *handle);?
函數(shù)描述:?
dlclose用于關(guān)閉指定句柄的動(dòng)態(tài)鏈接庫(kù),只有當(dāng)此動(dòng)態(tài)鏈接庫(kù)的使用計(jì)數(shù)為0時(shí),才會(huì)真正被系統(tǒng)卸載。
--------------------------------------------------------------------------------------------------------------------------
dlerror
dlerror()?
包含頭文件:?
#include <dlfcn.h>?
函數(shù)原型:?
const char *dlerror(void);?
函數(shù)描述:?
當(dāng)動(dòng)態(tài)鏈接庫(kù)操作函數(shù)執(zhí)行失敗時(shí),dlerror可以返回出錯(cuò)信息,返回值為NULL時(shí)表示操作函數(shù)執(zhí)行成功。
LINUX創(chuàng)建與使用動(dòng)態(tài)鏈接庫(kù)并不是一件難事。
編譯函數(shù)源程序時(shí)選用-shared選項(xiàng)即可創(chuàng)建動(dòng)態(tài)鏈接庫(kù),注意應(yīng)以.so后綴命名,最好放到公用庫(kù)目錄(如/lib,/usr/lib等)下面,并要寫(xiě)好用戶(hù)接口文件,以便其它用戶(hù)共享。
使用動(dòng)態(tài)鏈接庫(kù),源程序中要包含dlfcn.h頭文件,寫(xiě)程序時(shí)注意dlopen等函數(shù)的正確調(diào)用,編譯時(shí)要采用-rdynamic選項(xiàng)與-ldl選項(xiàng) ,以產(chǎn)生可調(diào)用動(dòng)態(tài)鏈接庫(kù)的執(zhí)行代碼
?
EXAMPLE
Load the math library, and print the cosine of 2.0:?
#include <stdio.h>
#include <dlfcn.h>
?
int main(int argc, char **argv) {
? ? void *handle;
? ? double (*cosine)(double);
? ? char *error;
?
? ? handle = dlopen ("libm.so", RTLD_LAZY);
? ? if (!handle) {
? ? ? ? fprintf (stderr, "%s\n", dlerror());
? ? ? ? exit(1);
? ? }
?
? ? cosine = dlsym(handle, "cos");
? ? if ((error = dlerror()) != NULL) ?{
? ? ? ? fprintf (stderr, "%s\n", error);
? ? ? ? exit(1);
? ? }
? ?printf ("%f\n", (*cosine)(2.0));
? ? dlclose(handle);
? ? return 0;
}
---------------------------------------------------------------------------------------------------
?If this program were in a file named "foo.c", you would build the program with the following command:?
?gcc -rdynamic -o foo foo.c -ldl
總結(jié)
以上是生活随笔為你收集整理的LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C语言: GDB调试技术(一)
- 下一篇: Linux Socket通信 C/S模型