对C/C++语言的库相关内容进行了总结,在平时项目中经常用到链接库,
虽然很多人都会用,但是对于其原因如何探究下去就是一种模糊的状态,可谓是知其然而不知其所以然,
为什么要链接库?静态库和动态库分别有什么特点?
自己什么时候该动态库,什么时候又该用静态库呢?
自己该如何编译一个库呢?
下面就以笔记的方式总结了一下。
旋风式介绍
- 库是什么?(二进制源代码)
- 二进制文件
- 将源代码-》二进制格式的源代码
- .c .cpp
- 能干什么:加密,保护知识产品,封装
- 怎么用?
- 静态库:
- gcc -c 参数生成 .o:
gcc a.c b.c -c
- 用ar rcs 进行打包:
ar rcs libtest.a a.o b.o
- 使用:编写测试程序test.c:
gcc test.c -L./ -ltest
- gcc -c 参数生成 .o:
- 动态库:
- gcc -c -fpic 参数生成 .o:
gcc a.c b.c -c
-fpic - 用gcc -shared 参数进行打包:
gcc -shared a.o b.o -o libtest.so
- 使用:编写测试程序test.c:
gcc test.c -L./ -ltest
- gcc -c -fpic 参数生成 .o:
- 静态库:
- 静态库优缺点
- 优点:
- 静态库被打包到应用程序中加载速度快
- 发布程序无需提供静态库,移植方便
- 缺点:
- 修改库里什么东西,都要重新编译整个项目,更新的时候很麻烦
- 就比如手机里有个游戏,每次更新都需要你重新安装APP,岂不是烦死了。。。
- 浪费系统资源(一些不同程序共用的库都得自行分别加载到内存),浪费内存
- 修改库里什么东西,都要重新编译整个项目,更新的时候很麻烦
- 优点:
- 动态库优缺点
- 优点
- 只有程序调用到动态库中的函数时候,才会把动态库加载到内存
- ld-linux 为动态链接器,负责调度这个过程
- 程序升级简单
- 可实现进程间资源共享
- 程序员可以控制何时加载动态库
- 只有程序调用到动态库中的函数时候,才会把动态库加载到内存
- 缺点
- 加载速度比静态库慢
- 发布程序需要提供依赖的动态库
- 优点
具体介绍
库制作出来之后,如何给用户使用?
- 头文件(使用说明)
- 制作出的库
静态库的制作和使用
命名规则:libtest.a
- 前缀lib
- xxx-库的名字
- .a
制作步骤:
- 原材料:源代码.c .cpp
- 将.c 生成.o
gcc a.cpp b.cpp -c
- 将.o打包
- ar rcs 静态库的名字 原材料
ar rcs libtest.a *.o
- ar rcs 静态库的名字 原材料
- nm可以查看静态库中有什么内容:
nm libtest.a
库的使用
- -L:指定静态库的文件所在的路径
- -l:指定静态库的名字
例:静态库文件名叫libtest.a:
gcc main.c -I ./include -L ./lib -ltest -o myapp
动态库的制作和使用.so
- 命名规则
- libxxx.so
- 制作步骤
- 将源文件生成.o
gcc a.c b.c -fpic(fPIC)
- 打包
gcc -shared -o libxxx.so a.o b.o
- 库的使用
- 头文件
- 动态库 libtest.so
- 链接:
gcc main.c -I ./include -L ./ -l test -o myapp
- 将源文件生成.o
- 查看库的链接:ldd myapp
- 动态库无法加载:
- 使用环境变量
- 临时设置:在终端:
export LD_LIBRARY_PATH=动态库的路径
- 为了不覆盖LD_LIBRARY_PATH内的值:用拼接写法:
export LD_LIBRARY_PATH=XXXXX:$LD_LIBRARY_PATH
- 为了不覆盖LD_LIBRARY_PATH内的值:用拼接写法:
- 永久设置
- 用户级别:
- ~/.bashrc
- 把shell语句
export LD_LIBRARY_PATH=XXXXX:$LD_LIBRARY_PATH
加到文件最后 - source ~/.bashrc :相当于重新对文件做个加载
- 系统级别:
- /etc/profile
- 修改完:source /etc/profile
- 用户级别:
- /etc/ld.so.cache 文件列表 (适用于库位置基本不变了)
- 找到一个配置文件
- /etc/ld.so.conf
- 把动态库的绝对路径添加到文件中
- 执行一个命令:
- sudo ldconfig -v
- 找到一个配置文件
- 临时设置:在终端:
- 使用环境变量
- 拓展方式:
- dlopen,dlclose,dlsym
- 命名规则