`
chriszeng87
  • 浏览: 717513 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

静态库和动态库的优缺点

阅读更多

一、库的类型

(一) 在windows中

.dll 动态库

.lib 静态库

库即为源代码的二进制文件

(二) 在linux中

.so 动态库

.a      静态库

 

(三) 静态库和动态库的优缺点

我们通常把一些公用函数制作成函数库,供其它程序使用。

函数库分为静态库和动态库两种。

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在

 

1.什么是库

在windows平台和linux平台下都大量存在着库。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

由于windows和linux的本质不同,因此二者库的二进制是不兼容的。

本文仅限于介绍linux下的库

 

2.库的种类

linux下的库有两种:静态库和共享库(动态库)。

 二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

 

3.库存在的意义

库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

 

4.库文件是如何产生的在linux下

静态库的后缀是.a,它的产生分两步

Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

Step 2.ar命令将很多.o转换成.a,成文静态库

动态库的后缀是.so,它由gcc加特定参数编译产生。

例如:

$ gcc -fPIC -c *.c $ gcc -shared -Wl,-soname, libfoo.so.1 -olibfoo.so.1.0 *.

 

5.库文件是如何命名的,有没有什么规范

在linux下,库文件一般放在/usr/lib和/lib下,

静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称

动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号

 

6.如何知道一个可执行程序依赖哪些库

ldd命令可以查看一个可执行程序依赖的共享库,

例如# ldd /bin/lnlibc.so.6

=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2

=> /lib/ld- linux.so.2 (0×40000000)

可以看到ln命令依赖于libc库和ld-linux库

 

7.可执行程序在执行的时候如何定位共享库文件

当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径

此时就需要系统动态载入器(dynamiclinker/loader)

对于elf格式的可执行程序,是由ld-linux.so*来完成的

它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib目录

找到库文件后将其载入内存

 

8.在新安装一个库之后如何让系统能够找到他

如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。

如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下

1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径

2.运行ldconfig,该命令会重建/etc/ld.so.cache文件

 

############################################################

 

 linux中编译静态库(.a)和动态库(.so)的基本方法

 

(四) 静态库

 

在linux环境中, 使用ar命令创建静态库文件.如下是命令的选项:

          d -----从指定的静态库文件中删除文件

          m -----把文件移动到指定的静态库文件中

          p -----把静态库文件中指定的文件输出到标准输出

          q -----快速地把文件追加到静态库文件中

          r -----把文件插入到静态库文件中

          t -----显示静态库文件中文件的列表

          x -----从静态库文件中提取文件

      还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:

          a -----把新的目标文件(*.o)添加到静态库文件中现有文件之后

          b-----***************************************之前

          v -----使用详细模式

ar 命令的命令行格式如下:

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

参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件.

 

比如创建一个静态库文件的命令如下:

      ar r libapue.a error.oerrorlog.o lockreg.o

这样就了libapue.a静态库文件, 可以用 t 选项显示包含在库中的文件

创建库文件之后,可以创建这个静态库文件的索引来帮助提高和库连接的其他程序的编译速度:

使用ranlib程序创建库的索引,索引存放在库文件内部.

      ranlib libapue.a

 

用nm程序显示存档文件的索引,它可以显示目标文件的符号

nm libapue.a | more

如果是显示目标文件的符号:

nm error.o | more

如何使用呢?如下所示:

gcc -o test test.c libapue.a

这样就可以在test.c中调用在libapue.a中的函数了.

 

 

(五) 动态库

 

1.创建共享库

     gcc -shared -o libapue.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/local/lib下,新建一个属于自己的目录apue,然后把刚才libapue.so复制过去就行了

同时在/etc/ld.so.conf中新增一行:

/usr/local/lib/apue

 

以后在编译程序时加上编译选项:

-L /usr/local/lib/apue -lapue

 

/*

参数的配置通过mangcc可以看到

-llibrary

              连接名为 library 的 库文件.

              连接器 在 标准搜索目录 中 寻找 这个 库文件, 库文件 的 真正 名 字

 

分享到:
评论
4 楼 shilei0619 2013-05-21  
shilei0619 写道
chriszeng87 写道
shilei0619 写道
8错,
ps.卤煮,头像是谁,好可爱的胖纸~

一个已经去世的日本音乐人

谁啊

我好像找到了,Nujabes,默哀
3 楼 shilei0619 2013-05-21  
chriszeng87 写道
shilei0619 写道
8错,
ps.卤煮,头像是谁,好可爱的胖纸~

一个已经去世的日本音乐人

谁啊
2 楼 chriszeng87 2013-05-20  
shilei0619 写道
8错,
ps.卤煮,头像是谁,好可爱的胖纸~

一个已经去世的日本音乐人
1 楼 shilei0619 2013-05-20  
8错,
ps.卤煮,头像是谁,好可爱的胖纸~

相关推荐

    动态库、静态库的创建与连接

    动态库与静态库的区别,各自的优缺点,动态库和静态库的创建方法与连接方法

    xcode 详解创建静态库和动态库的方法

    xcode 创建静态库和动态库 1、linux中静态库和动态库区别: 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 静态库:这类库的名字一般是libxxx.a;利用静态函数库编译...

    Linux静态库和动态库的制作

    (1)使用静态库生成的可执行文件大于动态库生成的可执行文件(程序占用的内存较多) (2)使用静态库生成的可执行文件难以升级,使用动态库生成的可执行文件易于升级 (3)使用静态库生成的可执行文件运行速度快,...

    深入探讨Linux静态库与动态库的详解(一看就懂)

    库分静态库和动态库两种。 一、静态库和动态库的区别1. 静态函数库这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大–空间,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,...

    和我一起做Linux动态库

    静态库以一种称为archive的特殊文件格式存放在磁盘中,静态库简化了我们的工作,在编译程序员工作中 十分重要,虽然静态库有其自身的重要性,但是与动态库相比,还是存在许多缺点,比如:静态库和所有的软件一样,...

    读取ini格式静态库

    因为作者在制作c++中找不到读取ini格式文件的方法,使用易语言制作了这个静态库,可以在大部分语言中使用,缺点:慢,体积大,详情见压缩文件里面的说明文件。

    VC + +中动态和静态连接库的实现 (2006年)

    介绍了静态连接库和动态连接 库的不同,以及它们的优缺点,并重点研究了动态连接库的实现方法。比较全面地介绍了静态连接库和动态连 接库在VC中的具体实现支持。最后,编程实现并分别在VB和VC中应用了DLL,实际的应用...

    完美编译libharu2.3.0开源PDF写入库

    libharu2.3.0开源PDF读写库,这是一个非常简洁短小的库,只依赖libpng和zlib库,使用非常方便。缺点是对Unicode支持不是很...完美编译了静态库、dll动态库四个版本,推荐使用dll版本库,不在额外需要其他静态库的链接。

    论文研究-动态服务的数据交换模型研究.pdf

    依据交换系统的现状,首先给出了静态服务库、动态服务库和静态交换系统、动态交换系统的概念;然后提出了动态服务的交换模型,并给出了交换的方法、原则和实现过程。最后,结合具体的应用实例,验证了模型的灵活性和...

    自己写的dll的简介

    1. 静态库适于稳定的代码,而动态库则适于经常更改代码(当然接口要保持不变),当DLL更改(仅实现部分)后,用户不需要重编工程,只需要使用新的Dll即可。 2. 由于静态库很吃可执行文件的生成(Link期)时间,所以...

    NiceBASICV 1.0中文编程正式版【MSI安装版】

    可以使用由标准C语言和汇编ASM编写的静态库(LIB)作为函数功能扩展。可以调用WIN32API的大部分函数,已经在内部定义(.bi文件相当于C语言的.h)声明,直接引用即可,就像C++的WINDOWS开发包(SDK)。 NB的编译器是...

    NiceBASIC V1.0中文编程正式版(绿色版).rar

    可以使用由标准C语言和汇编ASM编写的静态库(LIB)作为函数功能扩展。可以调用WIN32API的大部分函数,已经在内部定义(.bi文件相当于C语言的.h)声明,直接引用即可,就像C++的WINDOWS开发包(SDK)。 NB的编译器是...

    Echarts商业级数据图表库模块v1.6.0.241.rar

    echarts示例大全使用说明: 示例大全请下载对应版本的基础文件包。... 7)想要流畅运行复杂图形(k线图、大数据图),推荐cef3或v11以上的ie(当然ie不能运行js,无法动态改变图形配置和数据,cef3无限制)。

    论文研究-SET协议模型的改进与SMV分析.pdf

    现有的静态实视图选择算法存在搜索空间太大、时间复杂度高以及未考虑查询的概率和分布等诸多缺点,并且当源数据发生变化时,这种变化不能立刻反映到数据仓库,不适合在线运行。针对上述问题在候选视图生成算法和IGA...

    Imperfect C++ Practical Solutions for Real-Life Programming

    如何处理被C++标准所忽略的动态库、静态对象以及线程等有关的问题?隐式转换有何替代方案?本书将为你—一—解答这些问题。针对C++的每一个不完美之处,本书都具体地分析原因,并探讨实用的解决方案。书中也不乏许多...

    Java面试宝典2020修订版V1.0.1.doc

    18、JSP中动态INCLUDE与静态INCLUDE的区别? 37 19、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 38 20、页面传递对象的方法? 38 21、Cookied和session区别? 38 22、Filter的生命周期与执行过程 38...

    A_Platform_for_Secure_Static_Binary_Instrumentation.pdf

    无法被绕过 DBI(动态二进制插桩)容易做到以上两点,但SBI(静态二进制插桩)相对较难。加上易用性,所以之前安全插桩都选用DBI。不过DBI通常开销较大。 文中开发了一个PSI,克服了DBI技术的缺点,并且拥有安全,...

    VC程序在Win32环境下动态链接库(DLL)编程原理

    本文详细讲述了VC程序在Win32环境下动态链接库(DLL)编程原理。分享给大家供大家参考。具体分析如下: 一般比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的...

Global site tag (gtag.js) - Google Analytics