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. 萌新的九宫棋(C语言)
  2. 在网上找了一些j2ee的视频教程,有需要的朋友可以看看
  3. Android FrameWork学习(二)Android系统源码调试
  4. rsync+shell脚本完成自动化备份
  5. Go pprof 快速分析 CPU 高负载问题
  6. 使用border-collapse:collapse;属性新建一个细线表格
  7. Change code to ensure that OPA5 work also in WebIDE
  8. Stone game(dp计数上海icpc网络预选赛)
  9. 前端解析返回的对象时json显示$ref问题的解决
  10. 《假如编程是魔法之零基础看得懂的Python入门教程 》——(三)使用初始魔法跟编程魔法世界打个招呼吧
  11. python地图散点图_Python中基于Basemap的三维散点图
  12. html5按钮样式具有子项目,如何使用HTML5+css3制作出12种常用的按钮开关样式(附完整代码)...
  13. logistics回归分析+代码详解
  14. 《消费者报告》杂志:Model 3和Model S被评选为美国最佳豪华汽车
  15. DELL MD3200I存储单双控制器的自由切换
  16. 心情随笔(六):金秋十月备考之路亦别有一番风味
  17. Linux 命令(114)—— nl 命令
  18. 深度学习-从感知器到LSTM(目的是处理序列问题)
  19. Mysql跨表更新 多表update sql语句总结
  20. atitit。html css框架Bootstrap  Foundation的比较与不同 attilax大总结

热门文章

  1. HUAWEI AppGallery Connect 正式发布移动端App,随时随地掌握应用动态
  2. 【WEB前端】【报错解决】This request has been blocked; the content must be served over HTTPS....
  3. a76比a73强多少_实力称雄,Cortex A76架构性能大起底
  4. 影响世界的100条管理定律
  5. 【Bleak】六、特征及描述的发现
  6. 贵州省教师计算机培训,省教育厅办公室关于举办2017年中小学教师信息技术与学科教学教研深度融合专题培训班的通知...
  7. idea快速找到jar包位置
  8. Spring Boot Jpa 配置多个数据源,并读取其中一个表的具体数据
  9. 使用游标显示销售报表_oracle数据库期末考试试题及答案 -
  10. Android Studio ListView框架+优化安卓应用市场实例