通俗易懂说:dlopen、dlsym、dlclose动态链接库的加载

1. 什么是插件?

插件定义:
采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。
插件应用:
为了使程序方便扩展,具备通用性,可以采用插件形式。

2. 动态链接库的加载:dlopen、dlsym、dlclose

linux提供了加载和处理动态链接库的系统调用,dlopen、dlsym、dlclose。
接口定义:

#include <dlfcn.h>

void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);

2.1 dlopen

2.1.1 功能:

打开一个动态库,将其加载到进程地址空间中

2.1.2 原型

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

2.1.3 参数

第一个参数是:被夹在动态库的路径,可以绝对路径或者相对路径
第二个参数是:符号函数被解析的方式

  1. RTLD_LAZY 表示:使用延迟绑定,当函数第一次被用到时,才进行绑定,即 PLT 机制。
    优点:加载速度快
    缺点:如果后面有符号绑定出错将难以发现

  2. RTLD_NOW 表示:当模块加载时,即完成所有的函数绑定工作。
    优点:慢
    缺点:有错误及时发现

2.1.4 返回值:

被加载模块的句柄

2.2 dlsym:查找符号

void* dlsym(void* handle, char* symbol)
第一个参数是 dlopen 返回的句柄
第二个参数是 要查找的符号名,以\0结尾的字符串

dlsym如果找到符号就返回符号的地址或值,如果没有就返回NULL。

2.3 dlclose

dlclose来卸载打开的库
将一个已加载的模块卸载掉。

2.4 dlerror 错误处理

判断上一次执行是否正确,正确返回NULL,错误返回相应的错误值。

3. 代码实现计算sin(3.14/2)

dyTest.c

#include<stdio.h>
#include<dlfcn.h>

int main()
{
	void* handle;
	double (*func)(double);
	char* error;
	
	/* handle = dlopen("/lib/libm-2.6.1.so", RTLD_NOW); linux */
	handle = dlopen("/lib/x86_64-linux-gnu/libm-2.23.so", RTLD_NOW);
	if(handle == NULL){
		printf("open lib error: %s\n", dlerror());
		return -1;
	}
	
	func = dlsym(handle, "sin");
	if(NULL != (error = dlerror())){
		printf("symbol sin not found , error: %s\n",error);
		return -1;
	}
	
	printf("%f\n",func(3.1415926 / 2));
	dlclose(handle);
	return 0;
}

root@ubuntu-admin-a1:/home/6Chapter# gcc -o dyTest dyTest.c -ldl
root@ubuntu-admin-a1:/home/6Chapter# 
root@ubuntu-admin-a1:/home/6Chapter# ./dyTest 
1.000000
root@ubuntu-admin-a1:/home/6Chapter# 

-ldl 说明:
程序中使用dlopen、dlsym、dlclose、dlerror 显示加载动态库,需要设置链接选项 -ldl
-dl ,是显式加载动态库的动态函数库

4. 参考

(1 ) https://www.cnblogs.com/Anker/p/3746802.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值