一、静态库
(一)静态库的介绍
静态库是在程序编译链接阶段 ,其代码会被完整地**"复制"到最终生成的可执行文件** 中,成为可执行文件的一部分,编译完成后,静态库与可执行文件"绑定",运行时无需额外依赖;
特点:可执行文件独立运行,不依赖外部库文件;静态库会使可执行文件体积较大,但是效率比较高;若静态库更新,需重新编译链接程序;
静态库文件格式:windows平台下为**.lib** ;Linux平台下为**.a**;Mac平台下为.a;
(二)静态库制作及使用
准备源文件:编写实现库功能的源文件(如 .c或 .cpp);
编译生成目标文件:将源文件编译成目标文件(如 .o或.obj) ;gcc -c 源文件.c -o 目标文件.o
bash
gcc -c add.c -o add.o
打包生成静态库:使用归档工具将目标文件打包成静态库 ;ar -cr 静态库.a 目标文件.o
bash
ar -cr libmyadd.a add.o
编译主程序并链接静态库,生成可执行文件 ;gcc 目标文件.o -l库名 -L库路径 -o 可执行文件
cpp
gcc main.c -lmyadd -L. -o main
说明:如果库名是libmyadd.a,则库名是myadd,编译器会自动拼接lib前缀和.a后缀进行查找库文件。
bash
./main
二、动态库
(一)动态库的定义
动态库也称之为共享库,是在程序运行时才被加载到内存 中,可以被多个可执行文件共享使用,为它们提供函数、数据等资源。
特点:可执行文件运行时,需依赖系统中存在的动态库;可执行文件体积小,有效节省磁盘和内存空间;更新灵活 ,只要接口不变,无需重新编译依赖它的可执行文件;
动态库文件格式:windows平台下为.dll;Linux平台下为.so;Mac平台下为.dylib;
(二)动态库的制作
准备源文件:编写实现库功能的源文件(如 .c或 .cpp);
编译生成与位置无关的目标文件 :使用编译器编译源文件时,添加相关选项(如GCC的-fPIC选项)生成位置无关代码(PIC)的目标文件;gcc -c -fPIC 源文件.c -o 目标文件.o
bash
gcc -c -fPIC sub.c -o sub.o
链接生成动态库 :使用编译器将目标文件链接为动态库,多个程序可共享同一份动态库文件,节省内存;gcc -shared 目标文件.o -o 动态库.so
cpp
gcc -shared sub.o -o libmysub.so
编译时通过 -L指定路径 、 -l指定库名 生成可执行文件;gcc 源文件.c -l库名 -L库路径 -o 可执行文件
bash
gcc main.c -lmysub -L -o my_sub
运行时需通过 LD_LIBRARY_PATH 环境变量、 /etc/ld.so.conf 配置或系统路径,保证动态库可被加载;
-
示例1:通过LD_LIBRARY_PATH环境变量运行 ;export LD_LIBRARY_PATH=$PWD (=后面就是库路径,PWD表示当前路径)
bashexport LD_LIBRARY_PATH=$PWD -
示例2:通过**/etc/ld.so.conf 配置运行** ;编辑配置文件添加动态库路径:
sudo vim /etc/ld.so.conf (在此文件中添加动态库路径)bashpwd #查看当前的绝对目录:/home/hqyj/IO/dynamic_library sudo vim /etc/ld.so.conf #进入/etc/ld.so.conf,将当前路径加入
添加完成之后,执行sudo ldconfig命令更新系统缓存bashsudo ldconfig -
示例3:通过系统路径运行:优先考虑/usr/local/lib路径,然后进行更新系统缓存系统级库放/usr/lib,用户自定义库放 /usr/local/lib;
bash
sudo mv libmysub.so /usr/local/lib
sudo ldconfig #更新
三、静态库与动态库的区别
(1)链接方式:静态库在编译时链接,动态库在运行时链接;
(2)可执行文件体积:静态库使可执行文件体积大,动态库使可执行文件体积小;
(3)内存占用:多个程序使用同一静态库 时,每个程序都有一份库的副本 ,占用内存多 ;多个程序共享同一动态库 时,内存中只有一份库的副本,节省内存;
(4)更新维护:静态库更新需重新编译链接程序 ;动态库更新只需替换库文件,无需重新编译链接程序;
(5)依赖性:静态库无运行时依赖;动态库有运行时依赖,库缺失程序无法运行;
(6)适用场景:
- 静态库:适合对程序独立性要求高,库不常更新,且对可执行文件启动速度有要求的场景;
- 动态库:适合库需要频繁更新 ,多个程序共享库功能,且希望减小可执行文件体积的场景;
四、库制作常见问题及解决方案
(一)静态库链接时提示未定义的引用
可能原因:库文件路径错误、库名拼写错误、库中确实不存在该函数或变量的定义;
解决方法:检查库路径和库名是否正确,确认库中是否实现了所需功能;
(二)动态库运行时提示无法找到库文件
可能原因:库文件路径未加入系统默认搜索路径或者是未通过环境变量指定;
解决方法:将动态库复制到系统默认库路径(如/usr/local/lib),或设置相应的环境变量(如Linux的LD_LIBRARY_PATH);
(三)动态库版本冲突
可能原因:程序依赖的动态库版本与系统中安装的版本不一致;
解决方法:安装程序所需版本的动态库,或重新编译程序使其适配系统中的库版本;