动态库的检测和内存加载操作都是由动态链接器来完成的动态链接器是一个独立于应用程序的进程,属于操作系统 。当用户的程序需要加载动态库的时候动态连接器就开始工作了,很显然动态连接器根本就不知道用户通过 gcc 编译程序的时候通过参数 -L 指定的路径 。
那么动态链接器是如何搜索某一个动态库的呢,在它内部有一个默认的搜索顺序,按照优先级从高到低的顺序分别是:
- 可执行文件内部的 DT_RPATH 段 。
- 系统的环境变量 LD_LIBRARY_PATH 。
- 系统动态库的缓存文件 /etc/ld.so.cache 。
- 存储「静态库 / 动态库」的系统目录 /lib、/usr/lib 等 。
将动态库路径追加到环境变量 LD_LIBRARY_PATH 中:
$ LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:动态库的绝对路径
比如,我所需要的动态库的绝对路径为 /mnt/hgfs/SharedFolders/DynamicLibrary,那么:
$ LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/mnt/hgfs/SharedFolders/DynamicLibrary
这样的话,我在运行 main,就不会报错了 。
但是通过这种方式设置的环境变量尽在当前的终端中有效,那么怎样才能让这个设置永久生效呢?
通过指令
$ vim ~/.bashrc
打开并修改该文件:文章插图
修改后,使用
$ source ~/.bashrc
使修改立即生效 。经过上述操作,就不用每次开启终端都需要修改环境变量了 。当然这种永久生效的方式仅适用于动态库路径唯一的情况,如果你每次使用的动态库都在不同的位置,那么这么设置也没啥用2.4 动态库与静态库的比较2.4.1 静态库的特点
- 静态库对函数库的链接是在编译期完成的 。
- 静态库在程序编译时会链接到目标代码中,因此使可执行文件变大 。
- 当链接好静态库后,在程序运行时就不需要静态库了 。
- 对程序的更新、部署与发布不方便,需要全量更新 。
- 如果某一个静态库更新了,所有使用它的应用程序都需要重新编译、发布给用户 。
- 动态库把对一些库函数的链接载入推迟到程序运行时期 。
- 可以实现进程之间的资源共享,因此动态库也称为共享库 。
- 将一些程序升级变得简单,不需要重新编译,属于增量更新 。
- 为了使程序更加简洁不需要在项目中维护太多的源文件 。
- 另一方面是为了源代码保密,毕竟不是所有人都想把自己编写的程序开源出来 。
参考资料
- GCC | 爱编程的大丙 (subingwen.cn)
- GCC编译的四个阶段
- Linux 静态库和动态库 | 爱编程的大丙 (subingwen.cn)
- linux命令之ar—创建静态库.a文件
- 静态库和动态库 - 简书 (jianshu.com)
- linux中 ldd命令简介
- collect2: error: ld returned 1 exit status(解决方案大总结)
经验总结扩展阅读
- java中GC的日志认识详解
- 2023年摩羯座财运1月运程详解如何提高
- 我的世界指令附魔攻略(我的世界附魔1000级的指令)
- JUC中的AQS底层详细超详解
- 图文详解 微服务 Zipkin 链路追踪原理
- 电影谜一样的双眼剧情详解?
- 谍影重重4剧情详解?
- 西虹市首富剧情详解?
- 唐人街探案3剧情详解_唐人街探案3讲了什么剧情
- 2023年农历二月十八黄历宜忌详解