【深入理解】动静态库的制作、使用与加载原理(附详细操作指南)
一、什么是库?
库是可复用代码的二进制形式,可以被操作系统载入内存执行。库分为两种:
静态库:
.a(Linux)、.lib(Windows)动态库:
.so(Linux)、.dll(Windows)
库的存在避免了“从零开始”,提升了开发效率。
二、静态库
2.1 静态库的特点
编译链接时,库代码被直接嵌入到可执行文件中。
运行时不再依赖外部库。
生成的文件较大,但部署简单。
2.2 静态库的制作
使用 ar 工具将多个 .o 目标文件打包:
makefilelibmystdio.a: my_stdio.o my_string.oar -rc $@ $^
-rc:replace and create2.3 静态库的使用
gcc main.c -L. -lmystdio-L:指定库路径-l:指定库名(去掉lib和.a)
三、动态库
3.1 动态库的特点
程序运行时才链接库代码。
多个程序可共享同一库,节省内存和磁盘空间。
支持动态更新,无需重新编译程序。
3.2 动态库的制作
使用 gcc 的 -shared 和 -fPIC 选项:
makefilelibmystdio.so: my_stdio.o my_string.ogcc -shared -o $@ $^
%.o: %.cgcc -fPIC -c $<-fPIC:生成位置无关代码
3.3 动态库的使用
gcc main.c -L. -lmystdio3.4 动态库的搜索路径
如果运行时找不到动态库,可通过以下方式解决:
拷贝到系统路径:
/usr/lib、/usr/local/lib等设置
LD_LIBRARY_PATH环境变量使用
ldconfig更新缓存
四、ELF 文件格式
ELF(Executable and Linkable Format)是 Linux 下可执行文件、目标文件、共享库的标准格式。
4.1 ELF 文件的四种类型
可重定位文件(
.o)可执行文件
共享目标文件(
.so)核心转储文件
4.2 ELF 文件结构

| 组成部分 | 说明 |
|---|---|
| ELF Header | 文件头,描述基本信息 |
| Program Header Table | 程序头表,用于加载执行 |
| Section Header Table | 节头表,用于链接视图 |
| Sections | 代码、数据等具体内容 |
4.3 常见节(Section)
.text:代码.data:已初始化全局变量.bss:未初始化全局变量.rodata:只读数据.got:全局偏移表.plt:过程链接表
五、链接与加载过程
5.1 静态链接
将多个
.o文件合并成一个可执行文件。链接器会进行地址重定位,修正函数调用地址。
gcc -c hello.c code.c
gcc hello.o code.o -o main5.2 动态链接与加载
动态链接在程序运行时进行。

使用 GOT(全局偏移表) 和 PLT(过程链接表) 实现地址无关代码。
因为代码区是只读,不能修改,所以要将偏址放到数据区
支持延迟绑定,提高加载效率。
六、查看与分析工具
6.1 常用命令
| 命令 | 说明 |
|---|---|
readelf -h | 查看 ELF 头 |
readelf -l | 查看程序头表 |
readelf -S | 查看节头表 |
objdump -d | 反汇编代码段 |
ldd | 查看动态库依赖 |
nm | 查看符号表 |
6.2 示例:查看可执行文件结构
readelf -h a.out
readelf -l a.out
objdump -d a.out七、总结
| 对比项 | 静态库 | 动态库 |
|---|---|---|
| 链接时机 | 编译时 | 运行时 |
| 文件大小 | 大 | 小 |
| 内存使用 | 不共享 | 共享 |
| 更新维护 | 需重新编译 | 替换即可 |
| 适用场景 | 独立部署 | 多进程共享 |

