linux下C/C++开发小记2

一、dlopen函数

dlopen函数介绍

void * dlopen(const char* pathName, int mode);

在这里针对该函数的返回值,参数记录下自己的理解。

1.返回值

在加载库失败时会返回空指针,此时可以使用dlerror输出错误原因,至于为什么失败会与传入的参数有关。

2.pathName

要动态加载的库的名字,可以是相对路径也可以是绝对路径。个人建议为避免加载库错误最好是传入带有绝对路径的库名。
dlopen加载库的情况:1.如果filename中含有"/",且不是以“/”开头则是相对路径,是以Woking directoy进行相对查找;如果是以“/”开头,则是绝对路径。2.直接指定库的名字,不含“/”,此时查找库会以rpath->LD_LIBRARY->ld.so.cache->/lib,/usr/lib顺序进行查找。

3.mode

RTLD_LAZY:针对库中的函数,特指程序中实际用到的函数,在加载时不立马解析和重定位,只有在执行到函数所在位置时才解析函数符号,这样做的好处是提升加载库的速度,但坏处是:当实际用到的函数在实际执行过程中找不到地址信息时会造成整个程序的崩溃,但dlopen是返回的成功的,即没有第一时间返回错误。
RTLD_NOW:不同于RTLD_LAZY,在加载库时便会完成函数符号的解析和重定位工作,若有函数找不到地址(例如只声明了该函数,并在程序中使用该函数)则dlopen会立马返回NULL。注意RTLD_LAZY和RTLD_NOW必须手动设定一个。
RTLD_GLOBAL:打开的库会将自己的全局符号暴露到全局符号表中,这样会被后续加载的模块用来重定位。
RTLD_LOCAL:打开的库不会将自己的全局符号暴露到全局符号表中,这样也就不会被后续加载的模块用来重定位,默认使用改参数
RTLD_DEEPBIND:这个参数将在下文中进行解释。

二、dlsym函数

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

1.参数handle

1.当handle为NULL时,链接器会从全局符号表中去解析和重定位symbol;
2.当handle为有效模块指针时,链接器只会从指定的库中解析符号,若找不到则返回空指针。

三、显示动态加载的同名符号问题

在使用dlopen时同样会面临内部全局符号和外部全局符号重名的问题,这种问题带来的主要影响是:在使用dlsym拿到我们要使用的函数符号时(这个符号确实是指定加载库中的符号),但是该函数依赖模块内部的其他符号,但该符号与外部函数同名,这就会导致执行错误甚至崩溃。
为解决上述问题当然可以采用《linux下C/C++开发小记1》中说的在编译链接生成库的阶段搞定,而dlopen也为我们提供了解决思路那就是RTLD_DEEPBIND参数,使用该参数可以使被显示动态加载的模块优先使用其内部符号,而不是已存在与全局符号表中的符号

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值