静态库和动态库详解
静态库和动态库详解
1.什么是库
库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。
库是特殊的一种程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。
库文件有两种,静态库和动态库(共享库),区别是:
- 静态库在程序的链接阶段被复制到了程序中;
- 动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。
库的好处:
- 代码保密
- 方便部署和分发
2.静态库的制作
静态库的命名规则:
- Linux:
libxxx.a
- Windows:
libxxx.lib
静态库的制作:
gcc
获得 .o 文件- 使用
ar
工具(archive)将 .o 文件打包r
- 将文件插入备存文件中c
- 建立备存文件s
- 索引
1 | //add.c, sub.c, mult.c, div.c |
静态库的使用
链接时须注意头文件的展开和库文件的加载,另外还需注意目录层级。
1 | $ tree |
错误的做法:
正确的做法:
1 | # -I指定头目录,-l指定库名称,-L指定库路径 |
3.动态库的制作
动态库的命名规则
- Linux:
libxxx.so
(Linux下是一个可执行文件) - Windows:
libxxx.dll
动态库的制作
gcc
获得.o
文件,得到和位置无关的代码gcc
获得动态库
-fpic
用于汇编阶段,产生的目标文件没有绝对地址,全部用相对地址,这正好满足了共享库的要求,共享库被加载时地址不是固定的。如果不加 -fpic
,那么生成的目标文件就会与位置有关。
1 | $ gcc -c -fpic add.c sub.c div.c mult.c //生成.o文件 |
使用动态库
1 | $ gcc main.c -o dynamic_app -Iinclude -L../calc -lcalc |
TODO:实测加不加
-fpic
没什么区别,都是位置无关。
4.静态库和动态库的工作原理
- 静态库:GCC 进行链接时,会把静态库中代码打包到可执行程序中
- 动态库:GCC 进行链接时,动态库的代码不会被打包到可执行程序中
- 程序启动之后,动态库会被动态加载到内存中,通过
ldd
(list dynamic dependencies)命令检查动态库依赖关系 - 如何定位共享库文件呢?
- 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路 径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是 由
ld-linux.so
来完成的,它先后搜索elf文件的DT_RPATH
段 ——> 环境变量LD_LIBRARY_PATH
——>/etc/ld.so.cache
文件列表 ——>/lib/
,/usr/lib
目录找到库文件后将其载入内存。
- 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路 径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是 由
如何配置共享库文件?
- 临时配置(切换shell失效)
1 | # 处理生成app文件(app非必定名字) |
- 永久配置1(用户级)
1 | # 处理生成app文件(app非必定名字) |
- 永久配置2(系统级)
1 | # 处理生成app文件(app非必定名字) |
- 永久配置3(系统级,便捷)
1 | # 处理生成app文件(app非必定名字) |
5.静态库和动态库的区别
静态库、动态库区别来自链接阶段如何处理链接成可执行程序。分为静态链接方式和动态链接方式。
静态库优缺点
优点
- 静态库被打包到应用程序中加载速度快。
- 发布程序无需额外提供静态库,移殖方便。
缺点
消耗系统资源,浪费内存。
更新、部署、发布麻烦。
动态库优缺点
- 优点
- 可以实现进程间资源共享(共享库)。
- 更新、部署、发布简单。
- 加载动态库时间可控。
- 缺点
- 加载速度相对于静态库慢。
- 发布程序时需要提供依赖的动态库。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Raining的小站!
评论