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

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

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

linux中的显式运行链接---dlopendlsymdlerrordlclose搞起         之前, 我们在linux下制作过动态, 并卖过。 当我们采用的是隐式链接, 也就是说, 在代码中, 我们不用去管如何打开动态、如何链接(这些活都交给了链接器), 只需要管如何调用就行。  隐式链接的动态被进程加载到内存后, 就一直站着这个坑, 直到进程终结。 费费力, 浪费地盘, 而且不灵活。       于是, 一种动态加载(程序中指定加载)的方式就出现了, 这就是我们... 阅读详情

相关推荐

dlopendlsym的说明和使用-动态拿到函数地址

Linux提供了一套API来动态装载。下面列出了这些API: - dlopen,打开一个,并为使用该做些准备。 - dlsym,在打开的中查找符号的值。 - dlclose,关闭。 - dlerror,返回一个描述最后一次调用dlopendlsym,或dlclose的错误信息的字符串。 通过dlopen动态的打开动态,动态加载完成后,返回一个句柄,然后把句

com360的专栏 5686

Linux 中 dlopendlsymdlclosedlerror函数

编译候要加入 -ldl (指定dl) dlopen 基本定义 功能:打开一个动态链接 [喝小酒的网摘]http://blog.const.net.cn/a/17154.htm 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mode ); 函数描述: 在dlopen的()函数以指定...

LPetitPrince's Blog 3182

Linux C++ libdl.so dlfcn.h使用方法(dlopen()、dlsym()、dlclose()、dlerror())(用于动态链接操作)(懒加载、立即加载)共享符号、动态

RTLD_GLOBAL” 是 dlopen() 函数的一个标志,表示在打开共享将其中定义的符号全局可见,也就是说,共享中的符号可以被后续打开的其他共享所使用。是指在共享中定义的可以被其他共享和主程序使用的符号,这些符号在编译会被加入到共享的全局符号表中,并且可以通过 dlopen() 和 dlsym() 等函数在程序运行动态加载和使用。是指在共享中定义的只能被本地共享中的其他符号所使用的符号,这些符号在编译不会被加入到全局符号表中,只能在本地共享内部进行使用。

Dontla的博客 4671

LINUX下动态链接的使用(dlopen/dlsym/dlclose/dlerror

dlopen 功能:打开一个动态链接 包含头文件:#include <dlfcn.h> 函数定义:void * dlopen( const char * pathname, int mode ); 函数描述:在dlopen的()函数以指定模式打开指定的动态连接文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的。 mode:   RTLD_LAZY ...

$好记性还是要多记录$ 9169

诡异的bug之dlopen

本文我们从例子中看出来dlopen的解析符号的位置和顺序会影响程序的正确性。dlopen函数不仅仅是依赖于运行还依赖操作系统,不同操作系统上表现可能不一样尽量不要多个不同的ELF文件含有相同的符号,比如这个例子中我们就可以让单独一个so对factory及factory_register进行封装,大家都使用这个保证符号的单一性。排查问题可以使用readelf,nm,pmap等指令查看elf文件中的符号,以及运行符号所在的位置等。

leapmotion的博客 1235

dlopen dlsym dlerror dlclose 示例

【代码】dlopen dlsym dlerror dlclose 示例。

eloudy的专栏 318

UNIX下C语言编程实践11-UNIX 动态显式调用:dlopendlsymdlerrordlclose 函数的使用实例

本文详细介绍了UNIX环境下动态显式调用的原理实践。动态显式调用通过dlopendlsymdlerrordlclose四个核心函数实现,允许程序在运行动态加载和调用函数,相比隐式调用具有更高的灵活性。文章首先解析了各函数的功能和使用方法,强调错误检查的重要性;然后通过完整示例演示了从创建动态到显式调用的全流程;接着总结了常见错误及排查方法;最后分析了显式调用的适用场景(如插件开发、功能扩展)和局限性(代码复杂度高)。显式调用为模块化开发提供了强大支持,但也需要注意类型安全和调试难度等问题。

文石_2009的博客 1841

LINUX下动态链接的使用-dlopen dlsym dlclose dlerror【zt】

dlopen 基本定义   功能:打开一个动态链接   包含头文件:   #include   函数定义:   void * dlopen( const char * pathname, int mode );   函数描述:   在dlopen的()函数以指定模式打开指定的动态连接文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的

jernymy的专栏 5万+

显示运行链接dlopendlsymdlerrordlclose,)

支持动态链接的系统往往支持一种更灵活的模块加载方式,叫做显示运行链接(Eplict Run-time Linking),有也叫做运行加载。 就是在代码中运行,调用动态(.so文件),并这个动态的内部函数。 主要有以函数接口 void *dlopen(const char*filename, int flag) 参数1:const char*filename: 动态的路径 参数2:...

kayshi的博客 633

解决函数名冲突问题(dlopen,dlsym,dlclose)

背景 最近在4M布控球上集成城管算法的候有遇到一个问题,如图1所示,多个算法同提供同名函数但是具体实现却不同的情况,那么有个问题,当我们调用的候怎么确认调用的是某个静态中的函数?其实,当我们链接所有的静态候,如果遇到多个静态中符号名冲突的问题,先装载的符号会优先,那么后续相同符号就无法载入。也就是说,如果libA_his3519.a的HIKOBD_GetModelMemSize先加载,那么libB_hisi3519.a中的HIKOBD_GetModelMemSize就会无法加载进去,这候调

喵小林菌的博客 7684

linux动态函数dlopendlsym使用

为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接的形式加载进来,这就是所谓的插件。 linux提供了加载和处理动态链接的系统调用,主要涉及四个函数函数介绍如下: dlopen()函数 功能:打开一个动态链接[喝小酒的网摘]http://blog.const.net.cn/a/17154.htm 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const c...

tecoes的博客 9839

dlopen dlsym dlclose dlerror

dlopen  基本定义  功能:打开一个动态链接  包含头文件:  #include    函数定义:  void * dlopen( const char * pathname, int mode );   函数描述:  在dlopen的()函数以指定模式打开指定的动态连接文件,并返回一  个  句柄 给调用进程。使用dlclose()来卸载打开的。     mode:分为这

1298

通俗易懂说:dlopendlsymdlclose动态链接加载

通俗易懂说:dlopendlsymdlclose动态链接加载1. 什么是插件?2. 动态链接加载dlopendlsymdlclose2.1 dlopen2.2 dlsym2.3 dlclose3. 代码实现4. 参考 1. 什么是插件? 插件定义: 采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接的形式加载进来,这就是所谓的插件。 插件应用: 为了使程序方便扩展,...

哈尼的博客 3431

dlopen dlsym dlclose dlerror【zz】

从某处节选来的。   LINUX下动态链接的使用2.1 重要的dlfcn.h头文件LINUX下使用动态链接,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接函数的原型。下面详细说明一下这些函数。  2.1.1 dlerror  原型为: const char *dlerror(void);  当动态链接操作函数执行失

mosquitolxw的专栏 2754

LINUX下动态链接的使用(dlopen/dlsym/dlclose/dlerror)

dlopen 基本定义   功能:打开一个动态链接  包含头文件:#include <dlfcn.h>  函数定义:void * dlopen( const char * pathname, int mode );  函数描述:在dlopen函数以指定模式打开指定的动态连接文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的。   mode:分为这两种   RTLD_LAZY 暂缓决定,等有需要再解出符号   RTLD_NOW 立即决定,返回前解除所...

$好记性还是要多记录$ 1748

C语言--使用dlopendlsymdlclose运行装载动态

一个可执行程序可能多个动态有关联,通常是在程序运行将必要的动态装载入进程实体(内存中); 另外一种,则是使用dlopen/dlsym/dlclose来动态地将动态装载到当前进程实体中. 简单点说,就是: 1.dlopen将指定的动态以特定的方式装载到当前进程实体,并返回一个可操作的句柄,用以后续获取函数地址等操作; 2.dlsym从指定的(由dlopen的返回值指定)中获得指...

造梦先森Kai的专栏 3507

linux下so加载和使用(dlopen/dlsym/dlclose

转载自:http://www.cnblogs.com/gulvzhe/archive/2012/06/27/2565983.html 一. 函数简介 像window调用文件一样,在linux下,也有相应的API因为加载文件而存在。它们主要是以下几个函数函数名 功能描述 dlopen 打开对象文件,使其可被程序访问 dls

Invoker's Tower 1万+

转载: dlsym,dlopen,dlclose,dlerror如何使用

在项目中看到dlsym的使用,当不清楚这个函数的用法,参考了下面两个博文,思路清晰了,特作一个总结以备后面温习! 1、C语言中dlsym的小例子(一眼看出dlsym如何使用) 转载自:https://blog.csdn.net/sq1018/article/details/52727170 dlopen dlsym...

POTATO的博客 1109

Linux应用编程-动态加载动态 dlopen dlsym dlclose

动态加载so dlopen dlsym dlclose

hinewcc的博客 2635
上一篇: 动态链接的步骤与实现
下一篇: Linux 创建共享对象,共享库并安装使用共享库
Virtual_Func
博客等级 码龄11年 38粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值