显示运行时链接的函数与例子,dlopen,dlsym,dlerror,dlclose

Linux提供一组函数用来支持显示运行时链接,具体来说,有四个函数:打开动态链接库(dlopen),查找符号(dlsym),错误处理(dlerror),以及关闭动态库(dlclose)。这几个函数的声明与相关常量定义在系统标准头文件<dlfcn.h>中。


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

该函数用来打开动态库,并将其加载到进程的地址空间,完成初始化过程

返回值:由第一个参数指定的被加载模块的句柄

第一个参数:指定被加载的动态链接库的路径,如果是绝对路径,则直接查找;如果是相对路径,则按以下顺序查找:

(1)查找由环境变量 LD_LIBRARY_PATH 指令的一系列目录

(2)查找由 /etc/ld.so.cache 里面指定的共享库路径

(3)/lib、/usr/lib

*若该值为0,则返回全局符号表的句柄,也就是说可以在运行时找到全局符号表中的任意一个符号。


第二个参数:表示函数符号的解析方式

RTLD_LAZY:表示使用延迟绑定,当函数第一次被用到时才进行绑定。使用该参数,会导致符号未绑定的错误会在加载后发生,难以查到

RTLD_NOW:模块被加载时即完成所有函数的绑定工作。若模块加载时有任何符号未绑定,可以使用dlerror立即捕获。但加载速度变慢

RTLD_GLOBAL:与上述两者中一个一起使用,表示被加载的模块中的全局符号合并到全局符号表中


2.void * dlsym(void *handle,const char * symble)

该函数用来在打开的动态库中查找指定符号。

返回值:

(1)如果查找的是函数,则返回函数的地址

(2)如果查找的是变量,则返回变量的地址

(3)如果查找的是常量,则返回该常量的值

(4)如果没有找到符号,则返回NULL

*若查找的常量是NULL 或 0,可以通过dlerror判断是未查找到符号,还是返回的常量。如果符号找到了,dlerror() 返回NULL

第一个参数:使用dlopen打开的动态链接库的句柄

第二个参数:查找的符号,可以是函数,变量或常量


3.char * dlerror()

每次调用dlopen()、dlsym()、dlclose()以后,都可以调用dlerror()函数来判断上次调用是否成功。成功返回NULL,否则返回错误信息


4.int dlclose(void * handler)

将一个已经加载的模块卸载。使用引用计数的原理卸载。


一个例子:

动态链接文件:a.so。编译方式:g++ a.cpp -fPIC -shared -o a.so  (-shared 指定共享对象,-fPIC 指定与代码无关性)

/* a.cpp */
extern "C"    //该句很重要,指定编译器不要对min使用C++符号修饰规则
{
	int min(int a,int b)
	{
		return a < b ? a : b;
	}
}

测试文件:main.cpp  编译方式:g++ main.cpp -o main -ldl   (不加 -ldl 将无法找到 dlopen等函数)

#include <iostream>
#include <dlfcn.h>
using namespace std;
int main(int argc,char** argv)
{
	void * handle;
	int (*func)(int,int);
	char * error;
	handle = dlopen(argv[1],RTLD_NOW);	//打开链接库句柄
	if(NULL == handle)
	{
		cout << "can not open hanle" << endl;
		return -1;
	}
	func = reinterpret_cast< int(*)(int,int) >(dlsym(handle,"min"));   //查找符号Min,返回函数地址
	if((error = dlerror()) != NULL)
	{
		cout << "find symble min error : " << error << endl;
		return -1;
	}
	cout << "the test value is : " << (*func)(2,3) << endl;  //根据返回地址调用函数
	dlclose(handle);
	return 0;
}

执行指令:./main ./a.so

输出结果:2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值