1、 库的定义
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。所谓静态、动态是指链接。
2、 静态库
在链接阶段,将汇编生成的目标文件.0与引用到的库一起打包到可执行文件中,此种链接方式称为静态链接。
静态库特点总结:
静态库的链接是编译时期完成;
程序运行与函数库再无瓜葛,移植方便;
浪费空间与资源,如下图所示。
2.1 Linux下创建与使用静态库
静态库命名规则:必须是”lib[your_library_name].a”:lib为前缀,中间是静态库名,扩展名为.a。
静态库的创建流程:
首先将代码文件编译成目标文件.o:
gcc -c StaticMath.c
注意带参数-c,否则直接编译为可执行文件
然后,通过ar工具将目标文件打包成.a静态库文件:
ar –crv StaticMath.a StaticMath.o
静态库的使用:
gcc –o main main.c –I./StaticLib –L./StaticLib -lStaticMath
-Idirectory: 指定头文件搜索路径;
-Ldirectory:指定库文件搜索路径;
-llib:指定需要链接的库文件,省略前缀与后缀。
3、 动态库
静态库缺点:
1) 空间浪费
2) 全量更新
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例;可增量更新。
动态库特点:
动态库把函数库的链接载入到程序运行时期;
可实现进程之间资源共享(共享库);
增量更新;
可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。
3.1 Linux下创建使用动态库
动态库命名形式:libxxx.so,前缀是lib,后缀名为”.so”。
创建动态库:
- 首先,生成目标文件,此时要加编译器选项-fpic:
gcc –fPIC –c DynamicMath.c
-fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。
- 然后,生成动态库,此时要加链接器选项-shared
gcc –shared –o libdynamicmath.so DynamicMath.o
-shared指定生成动态链接库。
上面可合成一步:
gcc –fPIC –shared –o libdynamicmath.so DynamicMath.c
- 生成动态库文件后为了能让系统链接器在程序运行过程中能够成功载入该程序,需要将该动态库所在路径添加进/etc/ld.so.conf文件,或在/etc/ld.so.conf.d/目录下新建任何以.conf为后缀的文件,在该文件中加入库文件所在的目录,运行ldconfig,以更新/etc/ld.so.cache文件,否则会报error while loading shared libraries: libXXX.so.X: cannot open shared object file: No such file。
- 引用动态库编译成可执行文件(与静态库一致,这里不再赘述)