版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、动态库与静态库优缺点比较我们在编写一个 C 语言程序的时候, 经常会遇到好多重 复或常用的部分,如果每次都重新编写固然是可以的,不过 那样会大大降低工作效率,并且影响代码的可读性,更不利 于后期的代码维护。我们可以把他们制作成相应的功能函 数,使用时直接调用就会很方便,还可以进行后期的功能升 级。 例如我要在一段代码中多次交换两个变量的值, 我可以在代码中多次写入 i=x;x=y;y=i; 不过这样未免有点麻烦我们可以编写一个 change_two_int() 函数进行简化。定义如下函数:void change_two_int(int *a , int *b)int c;c=*a;*a=*b;
2、*b=c;这样每次要进行交换时只需调用 change_two_int(&x , &y); 即可,是否方便了许多? 那么我们要讨论的和这 些有什么关系呢?库通俗的说就是把这些常用函数的目标 文件打包在一起,提供相应函数的接口,便于程序员使用。 库是别人写好的现有的,成熟的,可以复用的代码,我们只 需要知道其接口如何定义,便可以自如使用。 现实 中每个程序都要依赖很多基础的底层库,不可能每个人的代 码都从零开始,因此库的存在意义非同寻常。比如我们常使 用的 printf 函数,就是 c 标准库提供的函数。我们在使用时 只需要包含相应的头文件就可以使用(非静态编译还要有相 应的库文件
3、) 。而不用关心 printf 函数具体是如何实现的, 这 样就大大提高了程序员编写代码的效率。从使用方法上分库 大体上可以分为两类:静态库和共享库。在 windows 中静态 库是以 .lib 为后缀的文件, 共享库是以 .dll 为后缀的文件。 在 linux 中静态库是以 .a 为后缀的文件, 共享库是以 .so 为 后缀的文件。以 linux 下的静态库和动态库为例我们研究一下,首先我们 看一下他们的生成方式静态库:首先将源文件编译成目标文件:gcc - c a.c b.c生成静态库:ar rc libstatic.a a.o b.o 共享库:同静态库一样编译成目标文件:gcc - c
4、 a.c b.c生成共享库: gcc - fPIC - shared - o libshared.so a.o b.o由此可见静态库和动态库都是对目标文件的处理,也可以说库文件已经是机器码文件了,静态库和共享库的加载过程有很大的区别。静态库的链接方法:gcc o staticcode L. Istatic main.c static(默认库在当 前文件夹 )共享库的链接方法:gcc - o sharedcode -L. - Ishared main.c(默认库在当前文 件夹)当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被 copy 到最终的可执行 文件中。这就会导致最
5、终生成的可执行代码量相对变多,相 当于编译器将代码补充完整了,这样运行起来相对就快些。 不过会有个缺点 : 占用磁盘和内存空间 . 静态库会被添加到 和它连接的每个程序中 , 而且这些程序运行时 , 都会被加载 到内存中 . 无形中又多消耗了更多的内存空间 . 与共 享库连接的可执行文件只包含它需要的函数的引用表,而不 是所有的函数代码,只有在程序执行时 , 那些需要的函数代 码才被拷贝到内存中。这样就使可执行文件比较小 , 节省磁 盘空间,更进一步,操作系统使用虚拟内存,使得一份共享 库驻留在内存中被多个程序使用,也同时节约了内存。不过 由于运行时要去链接库会花费一定的时间,执行速度相对会
6、慢一些,总的来说静态库是牺牲了空间效率,换取了时间效 率,共享库是牺牲了时间效率换取了空间效率,没有好与坏 的区别,只看具体需要了。另外,.一个程序编好后,有时需要做一些修改和优化,如果我们要修改的刚好是库函 数的话,在接口不变的前提下,使用共享库的程序只需要将 共享库重新编译就可以了,而使用静态库的程序则需要将静 态库重新编译好后,将程序再重新编译一便。 总结 : 一、库 的类型(一)在windows中.dll动态库.lib静态库库即为源代 码的二进制文件 (二) 在 linux 中 .so 动态库 .a 静态库 (三) 静态库和动态库的优缺点我们通常把一些公用函数制 作成函数库,供其它程序
7、使用。函数库分为静态库和动态库 两种。静态库在程序编译时会被连接到目标代码中,程序运 行时将不再需要该静态库。动态库在程序编译时并不会被连 接到目标代码中,而是在程序运行是才被载入,因此在程序 运行时还需要动态库存在 1.什么是库在 windows 平台和 linux 平台下都大量存在着库。 本质上来说库是一种可执行代 码的二进制形式,可以被操作系统载入内存执行。由于 windows 和 linux 的本质不同,因此二者库的二进制是不兼容 的。本文仅限于介绍 linux 下的库 2.库的种类 linux 下的库有 两种:静态库和共享库(动态库) 。 二者的不同点在于代码 被载入的时刻不同。静态
8、库的代码在编译过程中已经被载入 可执行程序,因此体积较大。共享库的代码是在可执行程序 运行时才载入内存的,在编译过程中仅简单的引用,因此代 码体积较小。 3.库存在的意义库是别人写好的现有的, 成熟 的,可以复用的代码,你可以使用但要记得遵守许可协议。 现实中每个程序都要依赖很多基础的底层库,不可能每个人 的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。4.库文件是如何产生的在linux下静态库的后缀是.a,它的产生分两步 Step 1由源文件 编译生成一堆.0,每个.0里都包含这个编译单元的符号表 Step
9、2.ar命令将很多.0转换成.a,成文静态库动态库的后缀 是.so,它由gcc加特定参数编译产生。例如:$ gcc -fPIC -c *.c$ gcc -shared -Wl,-s0name, libf00.s0.1 -0libf00.s0.1.0 *. 5. 库文 件是如何命名的,有没有什么规范在 linux 下,库文件一般 放在/usr/lib和/lib下,静态库的名字一般为libxxxx.a,其中xxxx 是该 lib 的名称动态库的名字一般为 libxxxx.s0.maj0r.min0r , xxxx 是该 lib 的名称, maj0r 是主版 本号, min0r 是副版本号 6.如何
10、知道一个可执行程序依赖哪 些库 ldd 命令可以查看一个可执行程序依赖的共享库, 例如 # ldd /bin/lnlibc.so.6=> /lib/libc.so.6 (0 x40021000)/lib/ld-linux.so.2=> /lib/ld- linux.so.2 (0 x 40000000) 可以看到 ln 命令依赖于 libc 库和 ld-linux 库 7.可执行程序在 执行的时候如何定位共享库文件当系统加载可执行代码时 候,能够知道其所依赖的库的名字,但是还需要知道绝对路 径此时就需要系统动态载入器 (dynamiclinker/l0ader) 对于 elf 格式
11、的可执行程序, 是由 ld-linux.s0* 来完成的它先后搜索 elf 文件的 DT_RPATH 段环境变量 LD_LIBRARY_PATH /etc/ld.so.cache文件列表一/lib/,/usr/lib目录找到库文件后将 其载入内存 8.在新安装一个库之后如何让系统能够找到他 如果安装在 /lib 或者 /usr/lib 下,那么 ld 默认能够找到,无需 其他操作。如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下1.编辑尼tc/ld.so.conf文件,加入库文件所在目录的路径2.运行 ldconfig ,该命令会重建/etc/ld.so.ca
12、che 文件# # linux中编译静态库(.a)和动态库(.so)的基本方法(四) 静态库 在 linux 环境中 , 使用 ar 命令创建静态库文件 . 如下是命令的选项 :d 从指定的静态库文件中删除文件m 把文件移动到指定的静态库文件中p 把静态库文件中指定的文件输出到标准输出q 快速地把文件追加到静态库文件中r 把文件插入到静态库文件中t 显示静态库文件中文件的列表x 从静态库文件中提取文件还有多个修饰符修改以上基本选项 ,详细请 manar 以下列出三个 :a 把新的目标文件 (*.o) 添加到静态库文件中现有文件之后b* 之前v 使用详细模式 ar 命令的命令行格式如下 : ar
13、-dmpqrtxabcfilNoPsSuvV membername countarchive files. 参数 archive 定义库的名称 , files 是库文件中包 含的目标文件的清单 , 用空格分隔每个文件 . 比如创建一个静态库文件的命令如下 : ar r libapue.a error.oerrorlog.o lockreg.o 这样就了 libapue.a 静态库文件 , 可以用 t 选项显示 包含在库中的文件创建库文件之后,可以创建这个静态库文件的索引来帮助提高和库连接的其他程序的编译速度:使用 ranlib 程序创建库的索引 ,索引存放在库文件内部.ranlib libap
14、ue.a 用 nm 程序显示存档文件的索引,它可以显示目标文件的符号 nm libapue.a | more 如果是显示目标文件的 符号 :nm error.o | more 如何使用呢 ?如下所示 :gcc -o test test.c libapue.a 这样就可以在 test.c 中调用在 libapue.a 中的函数了 (五 ) 动态库 1.创建共享库gcc -shared -olibapue.soerror.o errorlog.o 这样就创建了共享库 !2. 编译共享 库 假设共享库位于当前目录( 即跟程序文件相同的目录中 )gcc -o test -L. -lapue test.c 这样就编译出了不包含函数代 码可执行文件了 ,但是但你运行时会发现linux 动态加载器找不到 libapue.so 文件 .可以用 ldd 命令查看可执行文件依赖什 么共享库 :ldd test 如何才能让动态加载器发现库文件呢?有两种方法可以解决 :1.环境变量exportLD_LIBRARY_PATH='$LD_LIBRARY_PATH:.' 2. 修改 /etc/ld.so.conf 文件 . 一般应用程序的库文件不与系统库 文件放在同一个目录下 ,一般把应用程序的共享库文件放在 /usr/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教育机构生活管理制度大全(3篇)
- 伴侣宠物活动方案策划(3篇)
- 区块链保障医联体转诊数据安全与可信共享
- 康复护理中的营养支持
- 前列腺手术模拟训练的尿控功能保护转化
- 制剂辅料术语与全球药典标准体系
- 创面生长因子在糖尿病足中的应用
- 创新医疗器械能力建设与协同提升
- 创伤快速评分与急诊绿色通道的协同优化
- 减重手术患者术后疼痛呼吸抑制预防
- 2026年辽宁医药职业学院单招职业技能考试题库汇编
- 2025年人工智能在雕塑创作中的创新应用
- 国有林场松树移栽合同
- 电力设备故障检修报告模板
- 光伏电站试运行与交付标准指南
- 新部编人教版语文三年级下册写字表字帖 (一)
- 2026年高考作文备考之《子路、曾皙、冉有、公西华侍坐》素材积累与应用
- 汗水滴落+梦想起航+快闪课件-2025-2026学年高二上学期开学第一课主题班会
- 卵巢囊肿切除护理课件
- 叙事护理在老年患者中人文关怀的应用
- 幼儿园《新时代幼儿园教师职业行为十项准则》应知应会测试题及答案
评论
0/150
提交评论