#青训营 x 字节后端训练营# 动态库代码不会被打包到可执行程序中
程序启动后, 被动态加载到内存
## 命名规则
- Linux - libxxx.so
lib: 前缀 固定
xxx: 库名字
.so: 后缀固定
在Linux下是个可执行文件
- Windows - libxxx.dll
## 制作
- gcc得到.o文件, 得到和位置无关的代码
`gcc -c -fpic/-fPIC a.c b.c`
- 得到动态库
`gcc -shared a.o b.o -o libcalc.so`
## 使用
头文件也要分发给用户
`gcc main.c -I ./include/ -l calc -L ./lib/ -o app`
## 加载原理
- LDD(List Dynamic Dependencies)
`ldd app` 检查`app`的依赖关系
系统加载可执行代码时, 直到依赖库的名称, 但还需要具体绝对路径, 此时需要系统动态载入器获取绝对路径.
elf格式的可执行程序通过ld-linux.so完成
DT_RPATH -> 环境变量 LD_LIBRARY_PATH -> /etc/ld.so.cache文件列表 -> /lib/, /usr/lib目录找到库文件后将其载入内存.
通过修改环境变量实现
- export LD_LIBRARY_PAHT=$LD_LIBRARY_PATH:/home/ubuntu/lib/ (临时, 用户级)
- `. .bashrc` = `source .bashrc`
- 系统级 `/etc/profile`
## 静态库优缺点
优点
- 被打包到应用程序中, 加载速度快
- 发布程序无需提供静态库, 移植方便
缺点
- 消耗系统资源, 浪费内存(引用同一个静态库, 但内存中需要多份)
- 更新部署发布麻烦(库更新要重新编译)
## 动态库优缺点
优点
- 可以实现进程间资源共享(共享库)
- 更新部署发布简单
- 可以控制何时加载动态库
缺点
- 加载速度比静态库慢
- 发布程序时需要提供依赖的动态库