LV04-05-文件操作-链接库的使用
本文主要是C语言——链接库基本操作的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
开发板 | 正点原子 i.MX6ULL Linux阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
STM32开发板 | 正点原子战舰V3(STM32F103ZET6) |
点击查看本文参考资料
参考方向 | 参考原文 |
--- | --- |
一、链接库
前面我们已经学习过链接库的概念,包扩静态库和动态库。这一部分主要是针对函数调用动态库。可以看前面《01嵌入式开发/01HQ课程体系/LV02-编译基础/LV03-01-链接库*》部分的多篇笔记学习。这部分其实和前面有重叠,主要是不想删掉了,这里说明一下。
二、 通过函数调用动态库
1. dlopen()
在 linux 下可以使用 man 3 dlopen 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于打开指定名称的动态库,名称可以携带路径,然后返回一个句柄给调用进程。
【函数参数】
- filename : char 类型指针变量,表示要打开的动态库的名称,可以包含路径,如果文件名包含斜杠(“/”),则它将被解释为(相对或绝对)路径名。如果filename指定的对象依赖于其他共享对象,那么动态链接器也会使用相同的规则自动加载这些共享对象。(如果这些对象有依赖关系,这个过程可能会递归发生。)
- flags :int 类型,表示打开动态库的模式。
点击查看 flags 取值详情
- 必须要有以下两个值之一
1 | RTLD_LAZY : 执行惰性绑定。只在执行引用符号的代码时解析它们。如果符号从未被引用,那么它就永远不会被解析。(也就是说在 dlopen 返回前,对于动态库中存在的未定义的变量 (如外部变量 extern,也可以是函数) 不执行解析,就是不解析这个变量的地址。) |
还有一些可选的值,目前还没用过,后边用到了再补充。
【返回值】void *类型,成功时,dlopen()为加载的库返回一个非NULL句柄。如果出现错误(找不到文件、不可读、格式错误或在加载过程中产生错误),将返回NULL。
【使用格式】none
【注意事项】 none
3.2 dlclose()
在 linux 下可以使用 man 3 dlclose 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于关闭打开的动态库。
【函数参数】
- handle : void 类型指针变量,表示已经打开的动态库的句柄。
【返回值】int 类型,成功返回0,失败返回非0值。
【使用格式】none
【注意事项】 none
2. dlsym()
在 linux 下可以使用 man 3 dlsym命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于根据动态链接库操作句柄 (handle) 与符号 (symbol),返回符号对应的地址。
【函数参数】
- handle : void 类型指针变量,表示已经打开的动态库的句柄。
- symbol :char 类型指针变量,表示要查找地址的符号的名称。
【返回值】void *类型,成功返回与符号关联的地址,失败返回NULL。错误的原因可以使用dlerror(3)进行诊断。
【使用格式】none
【注意事项】 none
3. 使用实例
还是使用之前创建的动态链接库 libfile.so ,这里要先清除之前设置的环境变量LD_LIBRARY_PATH中关于该动态库的位置的相关语句,这样我们才能更清楚的看到使用dlopen会为我们带来哪些好处。我们修改主程序 test.c 如下:
1 |
|
然后我们编译程序:
1 | gcc test.c -o test -ldl |
这时候我们发现,我们并没有告诉链接器动态库的位置和名称,但是依然可以编译通过,我们执行程序,会得到以下输出:
1 | sum = 5 |
这说明,我们的程序正常执行了。