00. 目录
01. 概述
所谓“程序库”,简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分来完成某些功能。
库的存在可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。
程序库可分静态库(static library)和共享库(shared library)。
不管是Linux还是Windows中的库文件其本质和工作模式都是相同的, 只不过在不同的平台上库对应的文件格式和文件后缀不同。程序中调用的库有两种 静态库
和动态库
,不管是哪种库文件本质是还是源文件,只不过是二进制格式只有计算机能够识别。
在项目中使用库一般有两个目的,一个是为了使程序更加简洁不需要在项目中维护太多的源文件,另一方面是为了源代码保密,毕竟不是所有人都想把自己编写的程序开源出来。
当我们拿到了库文件(动态库、静态库)之后要想使用还必须有这些库中提供的API函数的声明,也就是头文件,把这些都添加到项目中,就可以我们的功能啦。
02. 静态库文件格式
静态库可以认为是一些目标代码的集合,是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分。
按照习惯,一般以“.a”做为文件后缀名。静态库的命名一般分为三个部分:
- 前缀:lib
- 库名称:自己定义即可
- 后缀:.a
所以最终的静态库的名字应该为:libxxx.a
【温馨提示】
- 在Linux中静态库以
lib
作为前缀, 以.a
作为后缀, 中间是库的名字自己指定即可, 即:libxxx.a
- 在Windows中静态库一般以
lib
作为前缀, 以lib
作为后缀, 中间是库的名字需要自己指定, 即:libxxx.lib
03. 静态库文件生成过程
生成静态库,需要先对源文件进行汇编操作 (使用参数 -c
) 得到二进制格式的目标文件 (.o 格式
), 然后在通过 ar
工具将目标文件打包就可以得到静态库文件了 (libxxx.a
)。
使用ar
工具创建静态库的时候需要三个参数:
参数c
:创建一个库,不管库是否存在,都将创建。参数s
:创建目标文件索引,这在创建较大的库时能加快时间。参数r
:在库中插入模块(替换)。默认新的成员添加在库的结尾处,如果模块名已经在库中存在,则替换同名的模块。
04. 静态库制作
4.1 源码结构如下所示
deng@local:~/tmp$ tree lib
lib
├── add.c
├── add.h
├── mdiv.c
├── mdiv.h
├── mul.c
├── mul.h
├── sub.c
└── sub.h
0 directories, 8 files
deng@local:~/tmp$
4.2 将所有的.c文件生成对应的.o文件
deng@local:~/tmp/lib$ gcc -c add.c
deng@local:~/tmp/lib$ gcc -c sub.c
deng@local:~/tmp/lib$ gcc -c mul.c
deng@local:~/tmp/lib$ gcc -c mdiv.c
deng@local:~/tmp/lib$ ls
add.c add.o mdiv.h mul.c mul.o sub.h
add.h mdiv.c mdiv.o mul.h sub.c sub.o
deng@local:~/tmp/lib$
# 或者以下方式
deng@local:~/tmp/lib$ gcc -c add.c sub.c mul.c mdiv.c
deng@local:~/tmp/lib$ ls
add.c add.o mdiv.c mdiv.o mul.h sub.c sub.o
add.h libtest.a mdiv.h mul.c mul.o sub.h
deng@local:~/tmp/lib$
4.3 生成静态库
deng@local:~/tmp/lib$ ar -rcs libtest.a add.o sub.o mul.o mdiv.o
deng@local:~/tmp/lib$ ls
add.c add.o mdiv.c mdiv.o mul.h sub.c sub.o
add.h libtest.a mdiv.h mul.c mul.o sub.h
deng@local:~/tmp/lib$
4.4 静态库发布
静态库制作完成之后,需要将.a文件和头文件一起发布给用户。
05. 静态库测试
5.1 工程结构如下所示
deng@local:~/tmp$ tree test/
test/
├── add.h
├── libtest.a
├── mdiv.h
├── mul.h
├── sub.h
└── test.c
0 directories, 6 files
deng@local:~/tmp$
5.2 编译test.c,生成可执行文件
deng@local:~/tmp/test$ gcc test.c -o test -I./ -L./ -ltest
参数说明:
- -L:表示要连接的库所在目录
- -I./: I(大写i) 表示指定头文件的目录为当前目录
- -l(小写L):指定链接时需要的库,去掉前缀和后缀
5.3 执行验证
deng@local:~/tmp/test$ ./test
x + y = 18
x - y = 12
x * y = 45
x / y = 5
deng@local:~/tmp/test$
06. 静态库优缺点
优点:
- 静态库被打包到应用程序中加载速度快
- 发布程序无需提供静态库,移植方便
缺点:
- 相同的库文件数据可能在内存中被加载多份, 消耗系统资源,浪费内存
- 库文件更新需要重新编译项目文件, 生成新的可执行程序, 浪费时间。
07. 技术交流
物联网、嵌入式、C++、C方向等等兴趣爱好者可以添加WX一起交流。 点击主页私信,添加博主微信。