一.库文件介绍
1.定义:
库文件是一组预先编译好的函数、类或数据的集合,以文件的形式存在,用于被其他程序调用;
库文件是一种可执行代码的二进制形式,是代码复用的一种方式
2.作用:
1.提高开发效率:避免重复编写相同功能的代码,减少开发时间;
2.便于代码维护:集中管理功能模块,修改和升级库时,只需更新库文件,无需修改使用库的程序;
3.保护代码隐私:可以将核心代码封装在库中,只提供接口供外部使用,隐藏实现细节;
3.分类:静态库和动态库
不同平台的库,有些无法跨平台。
静态库命名规则为:libxxx.a(以lib为前缀+自定义库名+.a后缀);
动态库命名规则为:libxxx.so(以lib为前缀+自定义库名+.so后缀);
动态库:libxxx.so.x.y.z
x 为主版本号,不兼容旧版;y 为次版本号,兼容旧版;z 为发行版本号,修复问题不影响接口
二.静态库介绍及制作
1.定义:
静态库是在程序编译链接阶段,其代码会被完整地”复制”到最终生成的可执行文件中,成为可执行 文件的一部分,编译完成后,静态库与可执行文件“绑定”,运行时无需额外依赖;
2.特点:
1.可执行文件独立运行,不依赖外部库文件;
2.静态库会使可执行文件体积较大,但是效率比较高;
3.若静态库更新,需重新编译链接程序;
静态库文件格式:
windows平台下为.lib;Linux平台下为.a;Mac平台下为.a
3.静态库制作及使用
1.准备源文件:编写实现库功能的源文件(如 .c或 .cpp);
2.编译生成目标文件:使用编译器将源文件编译成目标文件(如 .o或.obj);
示例:gcc -c 源文件.c -o 目标文件.o
3.打包生成静态库:使用归档工具将目标文件打包成静态库;
示例:ar -cr 静态库.a 目标文件.o
4.编译主程序并链接静态库,生成可执行文件;
示例:gcc 目标文件.o -l库名 -L库路径 -o 可执行文件
说明:如果库名是libmyadd.a,则库名是myadd,编译器会自动拼接lib前缀和.a后缀进行查找库文件;
4.静态库所用核心选项
三.动态库介绍及制作
1.定义:
动态库也称之为共享库,是在程序运行时才被加载到内存中,可以被多个可执行文件共享使用, 为它们提供函数、数据等资源;
2.特点:
可执行文件运行时,需依赖系统中存在的动态库;
可执行文件体积小,有效节省磁盘和内存空间;
更新灵活,只要接口不变,无需重新编译依赖它的可执行文件;
动态库文件格式:
windows平台下为.dll;Linux平台下为.so;Mac平台下为.dylib;
可执行文件
调用动态库1 ->动态库1
调用动态库2 ->动态库2
调用动态库3 ->动态库3
3.动态库制作及使用
1.准备源文件:编写实现库功能的源文件(如 .c或 .cpp);
2.编译生成与位置无关的目标文件:
使用编译器编译源文件时,添加相关选项(如GCC的-fPIC选项)生成位置无关代码(PIC)的目标文件;
示例:gcc -c -fPIC 源文件.c -o 目标文件.o
3.链接生成动态库:使用编译器将目标文件链接为动态库,多个程序可共享同一份动态库文件,节省内存;
示例:gcc -shared 目标文件.o -o 动态库.so
4.编译时通过-L指定路径、-l指定库名生成可执行文件;
示例:gcc 源文件.c -l库名 -L库路径 -o 可执行文件
运行时需通过LD_LIBRARY_PATH环境变量、/etc/ld.so.conf配置或系统路径,保证动态库可被加载;
四.静态库与动态库的区别
1.链接方式:静态库在编译时链接,动态库在运行时链接;
2.可执行文件体积:静态库使可执行文件体积大,动态库使可执行文件体积小;
3.内存占用:多个程序使用同一静态库时,每个程序都有一份库的副本,占用内存多;
多个程序共享同一动态库时,内存中只有一份库的副本,节省内存;
4.更新维护:静态库更新需重新编译链接程序;
动态库更新只需替换库文件,无需重新编译链接程序;
5.依赖性:静态库无运行时依赖;
动态库有运行时依赖,库缺失程序无法运行;
6.适用场景:
静态库:适合对程序独立性要求高,库不常更新,且对可执行文件启动速度有要求的场景;
动态库:适合库需要频繁更新,多个程序共享库功能,且希望减小可执行文件体积的场景;
五.库制作常见问题及解决方案
1.静态库链接时提示未定义的引用:
可能原因:库文件路径错误、库名拼写错误、库中确实不存在该函数或变量的定义;
解决方法:检查库路径和库名是否正确,确认库中是否实现了所需功能;
2.动态库运行时提示无法找到库文件:
可能原因:库文件路径未加入系统默认搜索路径或者是未通过环境变量指定;
解决方法:将动态库复制到系统默认库路径(如/usr/local/lib),或设置相应的环境变量(如Linux的 LD_LIBRARY_PATH);
3.动态库版本冲突:
可能原因:程序依赖的动态库版本与系统中安装的版本不一致;
解决方法:安装程序所需版本的动态库,或重新编译程序使其适配系统中的库版本;