程序运行中加载动态库,调用动态库函数

预备知识

linux 系统在程序中使用dlopen、dlsym、dlclose、dlerror 显式的加载动态库,需要设置链接选项 -ldl

加载动态链接库,首先为共享库分配物理内存,然后在进程对应的页表项中建立虚拟页和物理页面之间的映射。

你可以认为系统中存在一种引用计数机制, 每当一个进程加载了共享库(在该进程的页表中进行一次映射),引用计数加一;

一个进程显式卸载(通过dlclose等)共享库或进程退出时,引用计数减 一,

当减少到0时,系统卸载共享库


(1)打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag); dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

flag 参数

RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。

RTLD_NOW: 需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......


(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol); dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。

(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle); dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

 

库函数

#ifndef TEST_H
#define TEST_H

typedef int (*TEST_FUN)(void);

#endif
//test.c  gcc -c test.c -o test.o
//        gcc -shared test.o -o libtest.so
#include <stdio.h>
#include "test.h"

int test_fun(void)
{
	printf("This is a DLL!\n");
	return 0;
}

主函数

//main.c gcc main.c -o main -ldl
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "test.h"

int main()
{
	void *handle = NULL;
	TEST_FUN p = NULL;
	char *error = NULL;
	
	/* 打开动态链接库 */
	handle = dlopen("./libtest.so",RTLD_LAZY); 
	
	/* 动态库错误函数 */
	if((error = dlerror()) != NULL)
	{
		printf("%s\n",error);
		exit(1);	
	}
	
	/* 取函数(test_fun)执行地址 */
	p = (TEST_FUN)dlsym(handle,"test_fun");
	if((error = dlerror()) != NULL)
	{
		printf("%s\n",error);
		dlclose(handle);
		exit(1);	
	}
	
	p();
	dlclose(handle);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值