ref:https://blog.csdn.net/ostar_liang/article/details/14422423

之前用过这三个函数一直没时间整理一下。今天抽时间整理一下。

1、函数简介

dlopen

基本定义

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

返回值:
打开错误返回NULL
成功,返回库引用
编译时候要加入 -ldl (指定dl库)

dlsym()

功能:
根据动态链接库操作句柄与符号,返回符号对应的地址。
包含头文件:
#include <dlfcn.h>
函数定义:
void*dlsym(void* handle,const char* symbol)
函数描述:
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
handle是由 dlopen打开 动态链接库后返回的 指针,symbol就是要求获取的函数或 全局变量的名称。

dlclose()

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
 
上述都是摘抄,总结为链接的时候需要用到dl库,编译的时候需要加上dlfcn.h头文件。才能保证编译不会报错。
 
2、生成动态库
hello.c函数原型:

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>typedef struct {const char *module;int  (*GetValue)(char *pszVal);int   (*PrintfHello)();
} hello_ST_API;int GetValue(char *pszVal)
{int retval = -1;if (pszVal)retval = sprintf(pszVal, "%s", "123456");printf("%s, %d, pszVer = %s\n", __FUNCTION__, __LINE__, pszVal);return retval;
}int PrintfHello()
{int retval = -1;printf("%s, %d, hello everyone\n", __FUNCTION__, __LINE__);return 0;
}const hello_ST_API  Hello = {.module = "hello",GetValue,PrintfHello,
};

编译的时候用指令:
gcc -shared -o hello.so hello.c

上面的函数是用一个全局结构体hello来指向。在dlsym定义中说不仅可以获取函数的地址,还可以获取全局变量的地址。所以此处是想通过dlsym来获取全局变量的地址。好处自己慢慢体会。

3、dlopen代码

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>typedef struct {const char *module;int  (*GetValue)(char *pszVal);int   (*PrintfHello)();
} hello_ST_API;int main(int argc, char **argv)
{hello_ST_API *hello;int i = 0;void *handle;char psValue[20] = {0};handle = dlopen(“库存放的绝对路径,你可以试试相对路径是不行的", RTLD_LAZY);if (! handle) {printf("%s,%d, NULL == handle\n", __FUNCTION__, __LINE__);return -1;}dlerror();hello = dlsym(handle, "Hello");if (!hello) {printf("%s,%d, NULL == handle\n", __FUNCTION__, __LINE__);return -1;}if (hello && hello->PrintfHello)i = hello->PrintfHello();printf("%s, %d, i = %d\n", __FUNCTION__, __LINE__, i);if (hello && hello->GetValue)i = hello->GetValue(psValue);if (hello && hello->module){printf("%s, %d, module = %s\n", __FUNCTION__, __LINE__, hello->module);}dlclose(handle);return 0;
}

编译指令:gcc -o test hello_dlopen.c -ldl

运行./test结果如下。

PrintfHello, 27, hello everyone
main, 36, i = 0
GetValue, 19, pszVer = 123456
main, 42, module = hello

可以看到结果正常出来了。

看到没用?dlsym找到全局结构体hello后,可以直接用这个全局结构体指针来使用库里面的函数了,因为我们有时候提供的库不仅仅是一个两个函数的,一般的一个库都会存在多个函数,用这种方式就可以直接使用了。不然找函数名称的话要写多少个dlsym啊?

dlopen、dlsym和dlclose的使用和举例相关推荐

  1. linux dlopen 源码,采用dlopen、dlsym、dlclose加载动态链接库

    采用dlopen.dlsym.dlclose加载动态链接库 转载请标注,熬夜写的文章,挺辛苦 ... 环境 系统: 16.04.1-Ubuntu 编译器: gnu 5.4.0 python: 2.7. ...

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

    文章目录 dlfcn.h解析 - dlopen():打开一个动态链接库文件并返回一个句柄,该句柄用于后续的操作,如查找符号.关闭库等. - dlsym():在打开的动态链接库中查找指定的符号,并返回符 ...

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

    背景 最近在加载动态库的时候有遇到一个问题,如图1所示,多个动态库同时提供同名函数但是具体实现却不同的情况,那么有个问题,当我们调用的时候怎么确认调用的是某个静态库中的函数?其实,当我们链接所有的静态 ...

  4. dlopen、dlsym、dlclose

    dlopen.dlsym.dlclose都是作加载动态库之用.dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,dlerror返回出现的错误,dlsym通过句柄和连接符名称获取 ...

  5. Unity发布预审:检查出调用苹果禁用api: [dlopen, dlsym]

    表现: 打包出来的ipa在腾讯的wetest的ios预审中报以下错误. 最主要的就是这个[dlopen][dlsym],据公司的测试姐姐说这是苹果严打的对象.那么怎么从项目中找到问题代码并修改呢? 解 ...

  6. dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchan关于苹果禁用JSPatch(热修复一类),上架审核被拒问题

    应用很长一段时间没有上架了, 最近上了一次居然被打回来了,后续提交了很多次都被打回. 也跟苹果大大发了好几封邮件,但是依然无果 被拒原因具体如下 Hello, Thank you for your r ...

  7. android 禁用dlsym_[原创] 分享一个最近新撸增强版的绕过Android/iOS的dlopen/dlsym限制的dlfunctions库...

    简介 byOpen是一个绕过移动端系统限制的dlopen库. 支持特性 Android 支持App中加载和使用Android系统库接口(即使maps中还没有被加载也支持). Android 7以上dl ...

  8. 关于苹果过审2.5.2 dlopen dlsym问题

    苹果过审被拒绝检测出来dlopen dlsym问题 1.grep 命令搜索文件夹下文件里的符号 2.对ipa 里的可执行文件 和framework 进行搜索 3.如果找到了但是不知道哪个库调用的,用i ...

  9. 用g++编译生成动态连接库*.so的方法及连接(dlopen() dlsym() dlclose())

    ================================================================ //test_so_file.h ifndef TEST_SO_FIL ...

最新文章

  1. 动态 | DeepMind 首次披露旗下专利申请情况
  2. c#中对Cross-thread operation not valid错误的处理办法
  3. 顺序表的应用——逆置问题
  4. 在html文档中添加 iconfont 图标
  5. 状态机finite-state machine学习笔记1
  6. 光端机和无缝带拼接混合矩阵切换器的配搭应用-某市户外广告投屏解决
  7. 二维傅里叶变换简化方式
  8. 葫芦兄弟java7723_雪人兄弟(官方正版)
  9. 融资租赁产品计算内部收益率IRR
  10. word添加多个目录
  11. RTC与WebRTC有什么区别?
  12. 和ChatGPT的一番对话
  13. 硬实时RTLinux安装配置详解 (二):编译运行RTLinux
  14. stm8L051低功耗采集电池电量ADC例程
  15. 标签编辑软件linux,Ubuntu下安装音乐标签编辑软件Kid3 3.1
  16. 游戏地图和星际争霸地图技术
  17. MASK_RCNN与YOLO系列算法初学者笔记(摘抄自其他)
  18. mini——story3验收总结
  19. 时域分析——无量纲特征值含义一网打尽
  20. 离散数学实验一 真值计算

热门文章

  1. 小目标检测中的数据扩展
  2. Reactor设计模式 -- 基于EpollET模式
  3. ZZNUOJ_C语言1112:进制转换(函数专题)(完整代码)
  4. SAP应用中移动类型和移动原因的理解
  5. 京东高风险用户判定参考
  6. SMTP协议解析及C/C++代码实现
  7. 苹果和富士康力推的越南制造,或将被美国资本收割而成为泡影
  8. 基于微信小程序的长按录音、滑动取消发送功能实现~
  9. 对sam/bam文件进行操作
  10. CMOS图像传感器基础