linux下的静态库与动态库的区别和使用
linux下静态链接和动态链接的原理及应用
linux下静态链接和动态链接的原理及应用静态链接和动态链接是软件开发中常用的两种链接方式,用于将程序中的函数库和外部库文件与可执行文件进行关联。
本文将介绍静态链接和动态链接的原理和应用。
一、静态链接静态链接是指将程序中依赖的函数库和外部库文件的代码全部编译进最终生成的可执行文件中。
在静态链接的过程中,编译器会将源代码中的函数库和外部库文件的符号引用替换为符号定义,并将它们的机器码放入可执行文件中的相应位置。
静态链接的原理:1.链接器在进行静态链接时,将需要的函数库和外部库文件的代码复制到可执行文件的代码段中。
2.链接器将符号引用替换为符号定义,使得程序在执行时可以正确找到需要的函数库和外部库文件的代码。
3.链接器会解析符号的重定位信息,确定符号在可执行文件中的具体地址。
静态链接的优点:1.可执行文件中包含了所有需要的代码,因此在运行时不需要依赖外部函数库和动态链接器,可以独立运行。
2.静态链接可以减少程序的依赖性,使得程序更加稳定和可靠。
3.静态链接可以提高程序的执行性能,因为不需要在运行时加载外部库文件。
静态链接的缺点:1.可执行文件会变得较大,因为需要包含所有依赖的函数库和外部库文件的代码。
2.静态链接每次都需要将依赖的库代码复制到可执行文件中,因此每次编译都需要重新链接,导致编译时间较长。
3.如果多个可执行文件都依赖同一个函数库和外部库文件,会导致文件系统中存在多个相同的代码副本,浪费存储空间。
静态链接的应用:1.部署独立的可执行文件,不依赖任何外部库文件和动态链接器。
2.保证程序的稳定性和可靠性,避免由于外部库文件版本的变化导致程序错误。
3.减少系统中相同代码副本的数量,节省存储空间。
二、动态链接动态链接是指将程序中依赖的函数库和外部库文件的代码存放在独立的共享库文件中,程序在运行时通过动态链接器将共享库文件加载到内存中,并与可执行文件建立起关联。
动态链接的原理:1.可执行文件中只包含函数库和外部库文件的符号引用,不包含实际的代码。
linux下查看动态库和静态库的方法
linux下查看动态库和静态库静态库用ar -t YourFi le动态库用 nm -D YourFi le下面是ar和nm命令的一些参数说明1.ar基本用法ar命令可以用来创建、修改库,也可以从库中提出单个模块。
库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的memb er)。
原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
下面是ar命令的格式:ar [-]{dmpqrt x}[abcfil NoP sS uvV] [member name] [count] archiv e files...例如我们可以用ar rv libtes t.a hello.o hello1.o来生成一个库,库名字是te st,链接时可以用-ltest链接。
该库中存放了两个模块h ello.o和hell o1.o。
选项前可以有‘-‘字符,也可以没有。
下面我们来看看命令的操作选项和任选项。
现在我们把{dmpqrt x}部分称为操作选项,而[abcfil NoP sS uvV]部分称为任选项。
{dmpqrt x}中的操作选项在命令中只能并且必须使用其中一个,它们的含义如下:d:从库中删除模块。
按模块原来的文件名指定要删除的模块。
如果使用了任选项v则列出被删除的每个模块。
m:该操作是在一个库中移动成员。
当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。
如果没有指定任选项,任何指定的成员将移到库的最后。
也可以使用'a','b',或'I'任选项移动到指定的位置。
p:显示库中指定的成员到标准输出。
如果指定任选项v,则在输出成员的内容前,将显示成员的名字。
静态链接库和动态链接库的区别及优缺点
静态链接库和动态链接库的区别及优缺点动态链接库和静态链接库的区别本⽂参考了以下博客:1. /gamecreating/article/details/55041522. /left_la/article/details/120985453. /augusdi/article/details/6460415静态连接库就是把(lib)⽂件中⽤到的函数代码直接链接进⽬标程序,程序运⾏的时候不再需要其它的库⽂件;动态链接就是把调⽤的函数所在⽂件模块(DLL)和调⽤函数在⽂件中的位置等信息链接进⽬标程序,程序运⾏的时候再从DLL中寻找相应函数代码,因此需要相应DLL⽂件的⽀持。
静态链接库与动态链接库都是共享代码的⽅式,如果采⽤静态链接库,则⽆论你愿不愿意,lib 中的指令都全部被直接包含在最终⽣成的 EXE ⽂件中了。
但是若使⽤ DLL,该 DLL 不必被包含在最终 EXE ⽂件中,EXE ⽂件执⾏时可以“动态”地引⽤和卸载这个与 EXE 独⽴的 DLL ⽂件。
静态链接库和动态链接库的另外⼀个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,⽽在动态链接库中还可以再包含其他的动态或静态链接库。
动态库就是在需要调⽤其中的函数时,根据函数映射表找到该函数然后调⼊堆栈执⾏。
如果在当前⼯程中有多处对dll⽂件中同⼀个函数的调⽤,那么执⾏时,这个函数只会留下⼀份拷贝。
但是如果有多处对lib⽂件中同⼀个函数的调⽤,那么执⾏时,该函数将在当前程序的执⾏空间⾥留下多份拷贝,⽽且是⼀处调⽤就产⽣⼀份拷贝。
静态链接库与静态链接库调⽤规则总体⽐较如下:1、静态链接库(⽐较简单):⾸先,静态链接库的使⽤需要库的开发者提供⽣成库的.h头⽂件和.lib⽂件。
⽣成库的.h头⽂件中的声明格式如下:extern "C" 函数返回类型函数名(参数表);在调⽤程序的.cpp源代码⽂件中如下:#include "../lib.h"#pragma comment(lib,"..//debug//libTest.lib") //指定与静态库⼀起链接其次因为静态链接库是将全部指令都包含⼊调⽤程序⽣成的EXE⽂件中。
静态链接与动态链接的区别
静态链接与动态链接的区别动态链接库、静态库、import库区别动态链接库(Dynamic Linked Library): Windows为应⽤程序提供了丰富的函数调⽤,这些函数调⽤都包含在动态链接库中。
其中有3个最重要的DLL,Kernel32.dll,它包含⽤于管理内存、进程和线程的各个函数;User32.dll,它包含⽤于执⾏⽤户界⾯任务(如窗⼝的创建和消息的传送)的各个函数;GDI32.dll,它包含⽤于画图和显⽰⽂本的各个函数。
静态库(Static Library):函数和数据被编译进⼀个⼆进制⽂件(通常扩展名为.LIB)。
在使⽤静态库的情况下,在编译链接可执⾏⽂件时,链接器从库中复制这些函数和数据并把它们和应⽤程序的其它模块组合起来创建最终的可执⾏⽂件(.EXE⽂件)。
导⼊库(Import Library):在使⽤动态链接库的时候,往往提供两个⽂件:⼀个引⼊库和⼀个DLL。
引⼊库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。
在编译链接可执⾏⽂件时,只需要链接引⼊库,DLL中的函数代码和数据并不复制到可执⾏⽂件中,在运⾏的时候,再去加载DLL,访问DLL中导出的函数。
在运⾏Windows程序时,它通过⼀个被称作“动态链接”的进程与Windows相接。
⼀个Windows的.EXE⽂件拥有它使⽤不同动态链接库的引⽤,所使⽤的函数即在那⾥。
当Windows程序被加载到内存中时,程序中的调⽤被指向DLL函数的⼊⼝,如果DLL不在内存中,系统就将其加载到内存中。
当链接Windows程序以产⽣⼀个可执⾏⽂件时,你必须链接由编程环境提供的专门的“导⼊库(import library)库”。
这些导⼊库包含了动态链接库名称和所有Windows函数调⽤的引⽤信息。
链接程序使⽤该信息在.EXE⽂件中构造⼀个表,当加载程序时,Windows使⽤它将调⽤转换为Windows函数。
静态库与导⼊库的区别:导⼊库和静态库的区别很⼤,他们实质是不⼀样的东西。
动态库与静态库优缺点比较
动态库与静态库优缺点比较我们在编写一个C语言程序的时候,经常会遇到好多重复或常用的部分,如果每次都重新编写固然是可以的,不过那样会大大降低工作效率,并且影响代码的可读性,更不利于后期的代码维护。
我们可以把他们制作成相应的功能函数,使用时直接调用就会很方便,还可以进行后期的功能升级。
例如我要在一段代码中多次交换两个变量的值,我可以在代码中多次写入i=x;x=y;y=i; 不过这样未免有点麻烦我们可以编写一个change_two_int()函数进行简化。
定义如下函数:void change_two_int(int *a,int *b){int c;c=*a;*a=*b;*b=c;}这样每次要进行交换时只需调用change_two_int(&x ,&y);即可,是否方便了许多?那么我们要讨论的和这些有什么关系呢?库通俗的说就是把这些常用函数的目标文件打包在一起,提供相应函数的接口,便于程序员使用。
库是别人写好的现有的,成熟的,可以复用的代码,我们只需要知道其接口如何定义,便可以自如使用。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
比如我们常使用的printf函数,就是c标准库提供的函数。
我们在使用时只需要包含相应的头文件就可以使用(非静态编译还要有相应的库文件)。
而不用关心printf函数具体是如何实现的,这样就大大提高了程序员编写代码的效率。
从使用方法上分库大体上可以分为两类:静态库和共享库。
在windows中静态库是以.lib 为后缀的文件,共享库是以.dll 为后缀的文件。
在linux中静态库是以.a 为后缀的文件,共享库是以.so为后缀的文件。
以linux下的静态库和动态库为例我们研究一下,首先我们看一下他们的生成方式静态库:首先将源文件编译成目标文件:gcc –c a.c b.c生成静态库:ar –rc libstatic.a a.o b.o共享库:同静态库一样编译成目标文件:gcc –c a.c b.c生成共享库:gcc –fPIC –shared –o libshared.so a.o b.o由此可见静态库和动态库都是对目标文件的处理,也可以说库文件已经是机器码文件了,静态库和共享库的加载过程有很大的区别。
linux给运行程序指定动态库路径
linux给运⾏程序指定动态库路径1. 连接和运⾏时库⽂件搜索路径到设置库⽂件在连接(静态库和共享库)和运⾏(仅限于使⽤共享库的程序)时被使⽤,其搜索路径是在系统中进⾏设置的。
⼀般 Linux 系统把 /lib 和 /usr/lib 两个⽬录作为默认的库搜索路径【deepin可以在⾥⾯搜索出qt,因为deepin默认安装了qt程序运⾏依赖库】,所以使⽤这两个⽬录中的库时不需要进⾏设置搜索路径即可直接使⽤。
对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。
设置库⽂件的搜索路径有下列两种⽅式,可任选其⼀使⽤:(1). 在 /etc/ld.so.conf ⽂件中添加库的搜索路径。
(或者在/etc/ld.so.conf.d 下新建⼀个.conf⽂件,将搜索路径⼀⾏⼀个加⼊-junziyang)将⾃⼰可能存放库⽂件的路径都加⼊到/etc /ld.so.conf中是明智的选择添加⽅法也极其简单,将库⽂件的绝对路径直接写进去就OK了,⼀⾏⼀个。
例如:/usr/X11R6/lib/usr/local/lib/opt/lib需要注意的是:这种搜索路径的设置⽅式对于程序连接时的库(包括共享库和静态库)的定位已经⾜够了,但是对于使⽤了共享库的程序的执⾏还是不够的。
这是因为为了加快程序执⾏时对共享库的定位速度,避免使⽤搜索路径查找共享库的低效率,所以是直接读取库列表⽂件 /etc/ld.so.cache 从中进⾏搜索的。
/etc/ld.so.cache 是⼀个⾮⽂本的数据⽂件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库⽂件集中在⼀起⽽⽣成的(ldconfig 命令要以 root 权限执⾏)。
因此,为了保证程序执⾏时对库的定位,在 /etc/ld.so.conf 中进⾏了库搜索路径的设置之后,还必须要运⾏/sbin/ldconfig 命令更新 /etc/ld.so.cache ⽂件之后才可以。
动态库依赖动态库,静态库依赖静态库,顺序
动态库依赖动态库,静态库依赖静态库,顺序静态库依赖静态库,有顺序的问题,否则undefined reference⾄于动态链接,链接器会对依赖进⾏整理,避免这个问题。
动态库就不存在依赖顺序的问题。
如果库是相互独⽴的,则顺序不重要。
如果不是相互独⽴,那么必须对它们进⾏排序对于⽇常命令⾏编译命令,⼀般从左到右分别是可执⾏⽂件 ——> ⾼级库 ——> 底层库,避免循环依赖;越是底层的库,越是往后⾯写,可以参考下述命令通式:g++ ... obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib) -o $@静态库有顺序问题,并且要把⾃⼰的库所依赖的所有的第三⽅库都要显⽰的指定出来。
动态库⽆顺序问题,并且只需要显⽰的连接⾃⼰的动态库,⾃⼰的动态库依赖的第三⽅的动态库⽆需显⽰指定,⾃⼰会从rpath中⾃动连接第三⽅的动态库。
但必须把第三⽅库依赖的所有的库,包括路径都拷贝出来。
例如使⽤libevent.so, 此时需要把下⾯这⼀堆⽂件都拷贝出来:lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent-2.1.so.7 -> libevent-2.1.so.7.0.1-rwxr-xr-x. 1 root root 386024 Mar 25 15:18 deps/so/libevent-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core-2.1.so.7 -> libevent_core-2.1.so.7.0.1-rwxr-xr-x. 1 root root 241936 Mar 25 15:17 deps/so/libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core.so -> libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent.so -> libevent-2.1.so.7.0.1把第三⽅静态库链接到⾃⼰的.so动态库,编译第三⽅静态库的时候需要加 -fPIC这个参数。
c++静态库与动态库的区别
c++静态库与动态库的区别分类:C++2012-11-26 11:41 3621人阅读评论(1) 收藏举报如果对Linux下静态链接库和动态链接库感兴趣,请狂点击 -->你懂的一,概念1)静态链接库就是你使用的.lib文件,库中得代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。
使用方法1> 格式如:#pragma comment(lib,"XXX.lib")2> 针对开发环境:1、如果使用VC,可以在Project Setting-->Link中加入你的静态库,也可以直接把该.lib文件加入到你的工程中2、如果使用Visual Studio,位置在项目→配置属性→连接器→输入→附加依赖项中加入.lib文件构造方法在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.lib),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。
这个过程称为"静态链接",此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。
编程使用:使用lib需注意两个文件:(1).h头文件,包含lib中说明输出的类或符号原型或数据结构。
应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
(2).lib文件,见上面。
2)Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。
DLL 还有助于共享数据和资源。
多个应用程序可同时访问内存中单个DLL 副本的内容。
库的名词解释及意义
库的名词解释及意义首先,我们来解释一下什么是库。
在计算机科学中,库(Library)是指一组预先编译好的程序代码和资源文件的集合,这些代码和文件被组织在一个统一的文件或文件夹中,以供其他软件程序调用和使用。
库能够提供一些常用的功能和工具,帮助程序员快速开发应用程序,并具有重复使用的特点。
库可以分为两种不同的类型:静态库(Static Library)和动态库(Dynamic Library)。
静态库在程序编译时会被链接到目标程序中,成为程序的一部分,而动态库则是在程序运行时被加载到内存中,供程序使用。
静态库的优点在于,它能够使得程序的执行速度更快,因为在编译时已经将库的代码嵌入到了程序中,避免了运行时的加载过程。
而动态库的优点则在于,它可以被多个程序共享使用,节省了系统资源,并且能够在不重新编译程序的情况下更新库的版本。
库的意义在于它能够提供一些常见的功能和工具,使得程序员能够更高效地开发应用程序。
常见的库包括图形库、数据库访问库、网络库、数学计算库等等。
这些库能够为程序员提供一些封装好的函数和接口,简化了开发过程,降低了开发难度。
此外,库还可以提供一些标准化的资源文件,如图标、样式表等,使得应用程序的界面更加美观和统一。
以图形库为例,它可以提供一些函数和接口,使得程序员能够方便地绘制图形、处理图像、操作界面等。
不同的图形库有着不同的特点和优势,如OpenGL是一个跨平台的图形库,提供了强大的渲染功能,而OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和分析功能。
对于开发者而言,库的使用能够大大提高开发效率和质量。
通过使用库,程序员无需从零开始编写一些常见的功能,而是可以直接调用库中已经封装好的函数和接口。
这样不仅能够缩短开发周期,还能够减少错误和代码冗余,提高代码的可维护性和可扩展性。
此外,库的存在也促进了开源社区的发展。
开源库将自己的代码开放给其他人使用和修改,这样可以促进各种开源项目的合作和分享。
Linux下C语言函数库概述
总体概述,C语言的函数库可以有三种使用的形式:静态、共享和动态。
其中静态库的代码在编译时就已连接到开发人员开发的应用程序中。
而共享库只是在程序开始运行时才载入,在编译时, 只是简单地指定需要使用的库函数就可以了。
动态库则是共享库的另一种变化形式,它也是在程序运行时载入,但与共享库不同的是, 使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入,动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。
由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。
Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
静态函数库:每次当应用程序和静态连接的函数库一起编译时,任何引用的库函数中的代码都会被直接包含进最终的二进制程序。
共享函数库:包含每个库函数的单一全局版本,它在所有应用程序之间共享。
这一过程背后所涉及的机制相当复杂,但主要依靠的是现代计算机的虚拟内存能力,它允许包含库函数的物理内存安全地在多个独立用户程序之间共享。
区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,静态链接库通常以.a结尾(Archive的缩写)。
在终端缺省情况下,共享库通常为绿色,而静态库为黑色。
已经开发的大多数库都采取共享库的方式,Linux系统中目前可执行文件的标准格式为ELF(Executable and Linkable Format)格式。
ELF格式的可执行文件使得共享库能够比较容易地实现:.a的是为了支持较老的a.out格式的可执行文件,静态库文件, 可以用ar 命令生成。
.so的是支持elf格式的可执行文件的库,动态库文件,编译时加上指定的选项即可生成。
在linux系统中可用的库都存放在/usr/lib和/lib目录中。
