[Linux 高并发服务器]制作静态库与动态库
什么是库
- 库文件是计算机类的一类文件,可以当作代码仓库,提供给使用者一些可以直接拿来用的变量
函数和类 - 库不能单独运行
- 库文件用两种:静态库和动态库(共享库),区别是静态库在程序链接阶段被复制到了程序中,动态库在链接阶段没被复制到程序当中,而是在运行时由系统动态添加到内存中使用
- 库的好处:代码保密,方便部署和分发
静态库的制作和使用
命名规则
LINUX系统libxxx.a ,前缀lib和后缀.a固定,xxx为库名 Windows系统:libxx.lib
静态库的制作
gcc获得.o文件 将.o文件大宝,使用ar工具
ar rcs libxxx.a xxx.o xxx.o
r-将文件插入备存文件 c-创建备存文件 s-创建索引
静态库的使用
创建如下文件目录格式 使用打包好的libcalc.a 静态库需要静态库文件本身以及head.h 文件 main.c 文件为需要使用静态库的测试文件 使用如下命令把静态库编译链接到main.c
gcc main.c -o app -I ./include -l calc -L lib
-I 在哪里找头文件 -l 指定库的名称,主要不要写成libcalc.a ,calc 才是库名 -L 到哪里找库
动态库的制作和使用
命名规则
Linux:libxxx.so ,在Linux下是一个可执行文件 Windows:libxxx.dll
动态库的制作
gcc -c -fpic/-fPIC a.c b.c
-fpic 参数主要发生在编译->汇编的过程中
gcc -shared a.o b.o -o libcalc.so
.so 文件在LINUX下为可执行文件
使用动态库
参照静态库的使用方法输入
gcc main.c -o main -I ./include -L lib/ -l calc
但是在使用main的时候报错了
/main: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
原因是对于动态库而言,GCC进行链接是,动态库代码不会被打包到可执行文件当中 程序启动之后,动态库会被动态加载到内存中
我们可以通过ldd 命令来检查动态库依赖关系 当系统加载可执行带代码的时候,能够知道依赖库的名字,但还是需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so 来完成的(也就是图片中最后一行的玩意)
流程如下:
- DT_RPATH段
- 环境变量LD_LIBRARY_PATH
- /etc/ld.so.cache文件列表
- /lib/,/user/lib
所以就是动态库没被加载到吗,我们一个个流程去找就行了 对于DT_RPATH段,我们一般不用检查。
我们检查一下环境变量,使用env 命令即可查看我们的环境变量,发现貌似没有配置LD_LIBRARY_PATH,我们添加一下
方法一:直接在终端使用export配置 这种方法是临时的配置,关掉或者换个终端就没有了
export LD_LIBRARY_PASH=$LD_LIBRARY_PASH:这里进入到动态库文件目录然后pwd获取位置粘贴到这
tip: 如果要查询某个环境变量的值可以用echo
echo $LD_LIBRARY_PATH
方法二:在~ 目录下的.bashrc 文件中添加
export LD_LIBRARY_PASH=$LD_LIBRARY_PASH:这里进入到动态库文件目录然后pwd获取位置粘贴到这
然后使用
source .bashrc
保存应用设置 注意:如果你的shell不是bash改成了zsh之类的要去相应的配置文件修改例如.zshrc 这种方式是用户级别的
方法三:在/etc/profile 中按照方法二添加并保存
这种方式是系统级别,如果用户级别已经设置了可能会失效 我们使用unset 来删除已有的环境变量
方法四:把生成的动态库放到/lib/ 或者/usr/lib 目录
不推荐这种方法,因为本身里面就有很多库
添加后重新使用ldd 查询依赖,发现找到了,可以正常使用
静态库和动态库优缺点
静态库优点
- 静态库被打包到应用程序中加载速度快
- 发布程序无需提供静态库,移植方便
静态库缺点
- 消耗系统资源,浪费内存(可能好几个程序用相同的静态库,都被打包进去了)
- 更新部署发布麻烦
动态库优点
- 可以实现进程之间资源共享(共享库)
- 更新部署发布简单
- 可以控制何时加载动态库
动态库缺点
一般使用场景
库很小的话使用静态库 库比较大的花使用动态库
|