诺亚方舟

沉淀

Linux动态链接库与静态链接库

首先,我们来描述下链接库的作用。我们常用的动态链接库有标准库,编码时我们只需要引入头文件库函数的声明,即可调用标准库函数。为什么需要库文件,头文件?库文件实际上也是逻辑代码,当然我们也可以把逻辑逻辑代码写到同个程序文件下,那这样主程序文件就会显得很冗余,代码混乱,如果我们把某个功能抽象出来打包成二进制文件,调用方也只需要了解调用函数所需的参数和返回结果,也就是有头文件声明就可以,并不需要关心调用函数的实现过程,那么一切内容就会显得清晰明了,同时这样也利于代码的复用。

动态库和静态库的区别在于主程序对静态库的调用是在编译期,生成可执行文件后可以完全脱离静态库文件(运行期删除静态库文件也无所谓),而动态库的调用则不一样,动态库在编译器只是把符号链接上了,运行期还需要回到动态库文件里面调用函数,因此利用静态库生成的可执行程序体积会稍大,但是运行效率会稍快,使用动态库生成的可执行程序体积小,耦合性低,动态库可以实现热更。动态库名称一般是”libxxx.so”的规则,xxx就是你的库名,编译时gcc通过参数-lxxx指定;静态库的名称命名规则是”libooo.a”,ooo是库名,编译时gcc通过追加参数libooo.a指定(这里跟动态库方式不同,形式类似链接多个目标文件,个人理解静态链接库的形式和用法类似目标文件)。

下面介绍库的生成方法:

1)、静态链接库:

在linux环境中, 使用ar命令创建静态库文件.如下是命令的选项:
d —–从指定的静态库文件中删除文件
m —–把文件移动到指定的静态库文件中
p —–把静态库文件中指定的文件输出到标准输出
q —–快速地把文件追加到静态库文件中
r —–把文件插入到静态库文件中
t —–显示静态库文件中文件的列表
x —–从静态库文件中提取文件
还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:
a —–把新的目标文件(*.o)添加到静态库文件中现有文件之后
b —–*****************************之前
v —–使用详细模式
ar的详细说明请读者自行 man ar就可获得
ar 命令的命令行格式如下:

1
ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...

参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件. ar与archive中间的为上述的命令选项

2)、动态链接库:

动态链接库可以由目标文件xxx.o来生成,命令如下:

1
gcc -shared -o libxxx.so  xxx.o

如果我们生成了一个新的链接库地址,可以加到/etc/ld.so.conf文件中,ldconfig在系统启动的时候会执行一次,并将常用动态库缓存到/etc/ld.so.cache,里面保存了常用的动态函数库,且会先把他们加载到内存中,因为内存的访问速度远远大于硬盘的访问速度,这样可以提高软件加载动态函数库的速度,因此每次加新的动态库时需要执行ldconfig更新缓存文件。关于动态库和静态库的生成步骤详细可以看Linux下静态链接库与动态链接库的区别

介绍完库链接,下面我们介绍一个系统命令ldd,ldd可以查看可执行程序所依赖的动态库文件,类似lsof命令(这个命令则是用于查看执行器的进程所使用的库文件)。使用例子:

ldd

关于gcc头/库文件的查找,可以分为三类问题:头文件的查找、编译过程库文件的查找、运行过程库文件的查找。头文件的查找概念比较清晰,不再细述,后面两种查找的区别在于一个是在编译(链接)期,一个是在运行期。编译期的问题包括动态链接库、静态链接库,而运行期的问题只包括动态链接库,两个问题是不同的,一个是用于链接,寻找符号,一个是用于根据编译结果可执行程序中的符号进行调用。详细内容可以查看linux下的头文件和库文件搜索路径

参考文章:

linux中的ldd命令简介

静态链接库和动态链接库的区别及优缺点

Linux下静态链接库与动态链接库的区别

linux下动态与静态链接库的使用及区别

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>