0
点赞
收藏
分享

微信扫一扫

#导入Word文档图片# Linux下采用dlopen调用动态库的方法


一、前言

为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用,非常方便。

生成动态链接库语法:

gcc -fPIC -shared <源文件> -o libxxx.so

用法示例:

gcc -fPIC -shared sum.c -o libsum.so

二、dlopen系列函数

Linux提供以下4个函数用于处理动态库:

#include <dlfcn.h>

void *dlopen(const char *filename, int flag);

char *dlerror(void);

void *dlsym(void *handle, const char *symbol);

int dlclose(void *handle);

Link with -ldl. 注意: 编译时候要加入 -ldl (指定dl库)

2.1 dlopen函数介绍

功能:打开一个动态链接库

包含头文件: #include <dlfcn.h>

函数定义: void * dlopen( const char * pathname, int flag);

函数描述: 使用dlopen函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。完毕之后,使用dlclose()来卸载打开的库。

flag分为这2种

RTLD_LAZY 暂缓决定,等有需要时再解出符号

RTLD_NOW 立即决定,返回前解除所有未决定的符号。

返回值:

打开错误返回NULL

成功,返回库引用

使用dlopen:

dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。

示例代码:

#include <stdio.h>

#include <dlfcn.h>

int main()

{

int (*p)(int,int); //函数指针

void *handle;

/*1. 打开库文件*/

handle=dlopen("./sum/libsum.so",RTLD_LAZY);

if(handle==NULL)

{

printf("库打开失败!\n");

return 0;

}

/*2. 获取指定的函数地址*/

p=dlsym(handle,"sum");

if(p==NULL)

{

printf("函数地址获取失败!\n");

return 0;

}

//调用函数

printf("sum=%d\n",p(12,12));

/*3. 关闭库文件*/

dlclose(handle);

return 0;

}

2.2 dlsym()函数介绍

dlsym()的函数原型是:

void* dlsym(void* handle,const char* symbol)

该函数在<dlfcn.h>文件中。

handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数的名称,函数返回值是void*,指向函数的地址,供调用使用

dlsym根据动态链接库操作句柄(pHandle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。

比如,假设在so中定义了一个void mytest()函数,那在使用so时先声明一个函数指针:void (*pMytest)(), 然后使用dlsym函数将函数指针pMytest指向mytest函数,pMytest = (void (*)())dlsym(pHandle, "mytest");

2.3 dlclose函数介绍

包含头文件:#include <dlfcn.h>

函数原型为: int dlclose (void *handle);

函数描述: dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

2.4 dlerror函数介绍

包含头文件:#include <dlfcn.h>

函数原型: const char *dlerror(void);

函数描述:当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。



举报

相关推荐

0 条评论