Linux 下 C 语言静态库与动态库的制作及原理
什么是库
回顾一下 C 语言的编译流程,通常分为四个步骤:
- 预编译:处理头文件展开、宏替换等,生成
.i文件。 - 编译:进行词法、语法分析,翻译为汇编指令,生成
.s文件。 - 汇编:将汇编指令转换为二进制指令,生成
.o目标文件。 - 链接:将多个
.o文件链接成可执行程序。
生成的 .o 文件是可以打包的。将代码打包成库后,使用者只需链接即可运行,既方便又能隐藏源代码实现细节。库主要分为两类:
- 静态库:
.a(Linux)、.lib(Windows) - 动态库:
.so(Linux)、.dll(Windows)
注意:库文件名如
libmgc.a,去掉前缀lib和后缀.a才是库的实际名称。
认识动静态库
我们可以通过一个简单的示例来观察库文件的依赖情况。
#include <stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}
使用 ldd 命令查看可执行文件依赖的库:
ldd test
输出中显示的 libc.so.6 即为程序依赖的动态库。通过 file 命令可以确认其类型:
file /lib64/libc-2.17.so
结果显示这是一个共享库文件(动态库)。若要生成依赖静态库的可执行文件,需在编译时添加 -static 选项。此时再次使用 ldd 查看,将不再显示动态依赖信息,且生成的可执行文件体积通常比动态链接版本更大。
静态库
静态库的生成
为了演示清晰,我们采用声明与实现分离的方式编写两个函数:
printhello.h
#pragma once
extern void printhello();


