静态库、动态库的概念
静态库:在程序执行前(编译阶段)加入到目标程序中的库
动态库:在程序运行时动态(临时)由目标函数调用
库的优缺点
静态库
优点:
- 加载速度快:因为它在被打包时就已经加载到目标程序中了
- 发布程序时无需提供静态库:因为已经在程序中,移值方便
缺点:
- 冗杂:代码看起来不够清晰
- 更新、部署、发布麻烦
- 拷贝到可执行文件中时,多次使用会有多份冗杂拷贝
动态库
优点:
- 链接时不用复制,程序运行时由系统动态加载到内存中,提供给程序使用,只需要加载一次,而且可以给多个程序共用,节省内存
- 程序升级简单:因为app里没有库的源代码,升级后只要库的名字不变,函数原型不变,只需做代码优化即可
- 代码小而简洁
库的制作与使用
静态库
制作
因为我们写完的程序想要分享出去,但是又不想让别人看到我们的代码,我们就需要打包
为了以下说明方便
我们假设我们有以下文件:
main.c 主函数的代码文件
main.h 主函数用到的功能函数头文件
func.c 功能函数的代码文件
1.我们要准备好需要打包的 .c /.cpp文件,一般都是打包功能函数的文件,这里我们用到的是func.c
gcc ***.c -c (***.o) //生成.o文件
gcc func.c -c
2.将生成的func.o文件打包成静态库,静态库的后缀是.a
ar rcs ***.a ***.o (***.o ***.o…) //生成静态库
r :在库中插入(修改)模块(替换静态库)。当插入的模块名已经在库中存在,则替换同名的模块,如若干模块中有一个模块在库中不存在,则ar显示一个错误信息,并且不会替换其他同名模块
c :创建一个新的库。不管库是否存在,都将创建
s :创建目标文件索引,此参数在创建较大库时能加快时间。如果不需要创建索引, 可改写成S参数;如果.a文件缺少索引,可以使用ranlib命令来添加索引
ar rcs libfunc.a func.o
需要注意的是:一般库文件的命名是:lib+原名称+.a
使用
使用前首先要明确库 libfunc.a 是要给main.c使用的
gcc main.c -lfunc
此时编译器会报错,因为在默认路径下找不到库 func,这里先给出正确命令
gcc ***.c -lfunc -L ./ -o (***.out)
-l 的使用类似于头文件的使用,它优先查找 usr/lib 或者 /usr/local/lib 下是否有这个库
-L可以指定路径查找静态库 而-L ./则是优先查找当前路径下是否有目标库
gcc main.c -lfunc -L ./ -o main
使用的话直接
./main
动态库
参考:https://www.cnblogs.com/progamming/p/13043652.html
制作
gcc -shared -fpic **.c -o lib.?.so
-shared是指定生成动态库
-fpic是一种标准,生成目标文件选择该选项,生成位置无关的代码
gcc -shared -fpic func.c -o libfunc.so
使用
生成可执行文件的时候与静态库一样
gcc ***.c -lfunc -L ./ -o (***.out)
但是使用的时候就没有那么简单了,因为静态库是直接将库加载到程序中,而动态库是临时被目标程序引用,所以要添加环境变量,添加环境变量就需要用到export指令,但是它是添加临时环境变量,所以我们一般要写一个脚本来运行程序
gcc main.c -lfunc -L ./ -o main
/*
*vi main.sh
*/
chmod +x main.sh
./main.sh
main.sh
export LD_LIBRARY_PATH="/home/pi/test1"
//等号两边千万不要有空格,否则会不停报错
//./main.sh: line 1: export: `/home/pi/test1': not a valid identifier
//./main.sh: line 1: export: `=': not a valid identifier
./main