在读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");