Linux下c函数dlopen实现加载动态库so文件代码举例

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;
}
相关文章
相关标签/搜索