dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。这种机制使得在系统中添加或者删除一个模块时,都不须要从新编译了。能够在本身的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现。它须要两个参数:一个文件名和一个标志。文件名就是一个动态库so文件,标志指明是否马上计算库的依赖性。若是设置为 RTLD_NOW 的话,则马上计算;若是设置的是 RTLD_LAZY,则在须要的时候才计算。另外,能够指定 RTLD_GLOBAL,它使得那些在之后才加载的库能够得到其中的符号。当库被装入后,能够把 dlopen() 返回的句柄做为给 dlsym() 的第一个参数,以得到符号在库中的地址。使用这个地址,就能够得到库中特定函数的指针,而且调用装载库中的相应函数。由 www.169it.com 搜集整理html
在dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。linux
mode是打开方式,其值有多个,不一样操做系统上实现的功能有所不一样,在linux下,按功能可分为三类:函数
1 解析方式测试
RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用老是当即解析)。spa
RTLD_NOW:须要在dlopen返回前,解析出全部未定义符号,若是解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......操作系统
2 做用范围,可与解析方式经过“|”组合使用指针
RTLD_GLOBAL:动态库中定义的符号可被其后打开的其它库重定位。code
RTLD_LOCAL:与RTLD_GLOBAL做用相反,动态库中定义的符号不能被其后打开的其它库重定位。若是没有指明是RTLD_GLOBAL仍是RTLD_LOCAL,则缺省为RTLD_LOCAL。htm
3 做用方式进程
RTLD_NODELETE:在dlclose()期间不卸载库,而且在之后使用dlopen()从新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
RTLD_NOLOAD:不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,不然说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号,避免同名符号的冲突。这个flag不是POSIX-2001标准。
函数返回值:
打开错误返回NULL
成功,返回库引用
编译时候要加入 -ldl (指定dl库)
具体代码举例以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include "stdio.h"
#include
int
main(
int
argc,
char
*argv[])
{
char
module_name[1024]={
"./test_module.so"
};
char
*error=NULL;
void
*module_handle = dlopen(module_name, RTLD_NOW);
if
(module_handle == NULL)
{
error = dlerror();
char
tp[1024] = {0};
snprintf(tp, 256,
"Load module \"%s\" error: %s\n"
,
module_name, error);
printf
(
"%s"
,tp);
return
1;
}
else
{
printf
(
"Load module[%s] success!\r\n"
,module_name);
}
return
1;
}
|