静态库和动态库
什么是库:
本质上库是一种可执行代码的二进制形式,可以被操作系统直接载入到内容当中运行。库是别人写好的现成的,可以复用的代码,你可以直接使用库函数但是要记得遵守库的许可协议 —— C标准函数库
库存在的意义:
现实当中实现的每一个程序都需要依赖很多基础的函数库,不可能每个人的代码都从零开始,所以库存在的意义很重大,对于企业而言可以在不暴露接口的情况下提供程序服务。
linux下的库一共有两种:
静态库(.a,.lib)和动态库(.so,.dll)。两者的区别在于二进制代码载入程序的时刻不同
静态库在程序编译阶段会被链接在目标代码当中,程序运行时不再需要该静态库,但是程序会因此体积比较大
动态库在程序编译阶段并不会直接被链接到目标代码当中,而是当程序运行时才被载入,因此在程序运行时还需要有动态库的存在,但因此程序体积比较小。
编译成库文件的前提:
首先需要将实现代码进行拆分,分为.c文件以及.h文件
.c文件包含了函数的实现,.h里面包含头文件,结构体声明、宏定义、取别名以及函数声明
1.静态库(static library)
静态库的载入是在编译时期的链接阶段完成
优点:
- 静态库被打包在应用程序当中,加载速度比较快
- 发布程序无需要提供静态库,移植方便
缺点:
- 相同的库文件数据可能在内存当中被加载多份,消耗系统资源,浪费资源
- 库文件更新的时候需要所有使用该库的程序重新编译项目文件,生成可执行程序,浪费时间
创建静态库:
- 准备需要编译静态库.c文件
- 生成制作库文件所需要的功能函数的对象文件.o
gcc -c linklist.c -o linklist.o
- 生成静态库
ar crs liblinklist.a linklist.o
libxxx.a
静态库的标准命名格式
- 使用静态库
gcc main.c -o main -L. -llinklist
-L
指定静态库的路径
-l
指定静态库名
2.动态库 (dynamic library)
程序使用动态库时,在编译阶段,在程序当中只会有一个指向,也就说当可执行文件需要用到动态库函数时,程序才会去读取动态库载入使用
优点:
- 动态库升级简单,只要替换动态库,无需重新编译程序
- 可以控制何时加载动态库,不调用的不会加载动态库
缺点:
- 程序加载速度比静态库要慢
- 发布程序时需要依赖动态库
创建动态库:
- 准备需要编译动态库.c文件
- 生成制作文件库所需要的函数的对象文件.o
gcc -fPIC -c linklist.c -o linklist.o
-fPIC
生成的动态库在内存当中去自动寻找一块合适的内存进行存储
- 生成动态库文件
gcc -shared linklist.o -o liblinklist.so
libxxx.so
动态库的标准命名规范
- 使用动态库
gcc main.c -o main -linklist
如果直接编译一般会出错,原因使直接编译找不到动态库的文件,为了程序能顺利找到动态库,我们一般会把动态库放在/lib
,再进行编译。