连接库是windows的术语,但对于Linux来讲,其概念是同样的。咱们一般会把一些类似或相近功能的程序生成连接库,这样的好处是:windows
1)便于共享,开发软件时如须要相同功能时,不须要将大量重复的代码整合到工程当中,直接调用便可。模块化
2)便于保密,连接库是二进制的,源代码是不可见的。函数
连接库有动态与静态两种,Linux动态库一般用.so为后缀,静态库用.a为后缀。性能
(1)静态连接,在这种连接方式下,函数代码将从其所在的静态连接库中拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态连接库其实是一个目标文件的集合,其中的每一个文件含有库中的一个或者一组相关函数的代码。spa
(2)动态连接,在此种方式下,函数的代码被放到称做是动态连接库或共享对象的某个目标文件中。连接程序此时所做的只是在最终的可执行程序中记录下共享对象的 名字以及其它少许的登记信息。在此可执行文件被执行时,动态连接库的所有内容将被映射到运行时相应进程的虚地址空间。动态连接程序将根据可执行程序中记录的信息找到相应的函数代码。对象
对于可执行文件中的函数调用,可分别采用动态连接或静态连接的方法。使用动态连接可以使最终的可执行文件比较短小,而且当共享对象被多个进程使用时能节约一些内存,由于在内存中只须要保存一份此共享对象的代码。但并非使用动态连接就必定比使用静态连接要优越。在某些状况下动态连接可能带来一些性能上的损害。进程
静态库和动态库的区别内存
1.利用静态函数库编译成的文件比较大,由于整个函数库的数据会被整合进目标代码中,他的优势就显而易见了,即编译后的执行程序不须要外部的函数库支持,由于全部使用的函数都已经被编译进去了。固然这也会成为他的缺点,由于若是静态函数库改变了,那么你的程序必须从新编译。资源
2.相对于静态函数库,动态函数库在编译的时候并无被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,所以动态函数库所产生的可执行文件比较小。因为函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,因此程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,因此动态函数库的升级比较方便。开发
使用静态库的好处:
1,模块化,分工合做
2,避免少许改动常常致使大量的重复编译链接
3,也能够重用,注意不是共享使用
使用动态库的好处:
1,能够将最终可执行文件体积缩小
2,多个应用程序共享内存中得同一份库文件,节省资源
3,能够不从新编译链接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
不管是静态库文件仍是动态库文件,都是由目标文件(即 .o 文件)建立的,注意库中函数不能有main函数。
静态库的应用
1) 静态库的建立
静态库文件的命名规范是以lib开头,以.a结尾。如libmymath.a
ar cr libmymath.a mymath.o
2) 静态库的使用
①直接连接
gcc main.c libmymath.a
②在使用到这些公用函数的源程序中包含这些公用函数的原型声明,而后再用gcc命令生成目标文件时指明所使用的静态库名(是mymath 而不是libmymath.a ),gcc将会从静态库中将公用函数链接到目标文件中。注意,gcc会自动在静态库名前加上前缀lib,而后追加扩展名.a获得的静态库文件名来查找静态库文件。
gcc main.c -L. -lmymath
参数说明:-L指明静态库文件所在路径,-l指明所要使用的静态库。
动态库的应用
1) 动态库的建立
动态库文件名命名规范与静态库相似,以lib开头,以.so结尾。如:libmymath.so。
gcc -shared -fPCI -o libmymath.so mymath.o
注意-fPIC选项。PIC指Position Independent Code。共享库要求有此选项,以便实现动态链接(dynamic linking)。表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的因此动态载入时是经过代码拷贝的方式来知足不一样进程的须要,而不能达到真正代码段共享的目的。
2) 动态库的使用
①直接连接
gcc main.c ./libmymath.so
②与静态库的使用基本一致,参数意义也相同,编译器会先搜索libxxx.so文件,若是没有找到,继续搜索libxxx.a(静态库)。
gcc main.c -L. -lmymath
加载动态库生成的可执行文件运行时一样须要使用该动态库,所以必须告诉程序该动态库的路径,不然程序运行将会出错。
为了让执行程序顺利找到动态库,有三种方法:
①把库拷贝到/usr/lib和/lib目录下。
②在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libmymath.so在当前目录下。‘.’表示当前目录,用‘:’隔开
使用命令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
③修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行sudo ldconfig刷新(须要超级用户权限)。
注:
查看依赖动态库库命令:ldd
查看可执行文件的符号:nm