一、什么是库?
在windows平台和linux平台下都大量存在着库。一般是软件作者为了发布方便、替换方便或二次开发目的,而发布的一组可以单独与应用程序进行compile time或runtime链接的二进制可重定位目标码文件。
本质上来说库是一种可执行代码的二进制形式,这个文件可以在编译时由编译器直接链接到可执行程序中,也可以在运行时由操作系统的runtime enviroment根据需要动态加载到内存中。
一组库,就形成了一个发布包,当然,具体发布多少个库,完全由库提供商自己决定。
由于windows和linux的本质不同,因此二者库的二进制是不兼容的。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
本文仅讨论linux下的库。
二、库的分类
库有两种:静态库和共享库(动态库)。
win32平台下,静态库通常后缀为.lib,动态库为.dll ;
linux平台下,静态库通常后缀为.a,动态库为.so 。
从本质上来说,由同一段程序编译出来的静态库和动态库,在功能上是没有区别的。不同之处仅仅在于其名字上,也就是“静态”和“动态”。
二者均以文件的形式存在,其本质上是一种可执行代码的二进制格式,可以被载入内存中执行。无论是动态链接库还是静态链接库,它们无非是向其调用者提供变量、函数和类。
1. 静态库
所谓静态库,就是在静态编译时由编译器到指定目录寻找并且进行链接,一旦链接完成,最终的可执行程序中就包含了该库文件中的所有有用信息,包括代码段、数据段等。
2. 动态库
所谓动态库,就是在应用程序运行时,由操作系统根据应用程序的请求,动态到指定目录下寻找并装载入内存中,同时需要进行地址重定向。
3. 区别
我们以编译链接、载入时刻两点来讨论静态库和动态库的区别。
编译链接
静态链接库在程序编译时会被链接到目标代码中,目标程序运行时将不再需要改动态库,移植方便,体积较大,浪费控件和资源,因为所有相关的对象文件与牵涉到库都被链接合成一个可执行文件,这样导致可执行文件的体积较大。
动态库在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入,因为可执行文件体积较小。有了动态库,程序的升级会相对比较简单,比如某个动态库升级了,只需要更换这个动态库的文件,而不需要去更换可执行文件。但要注意的是,可执行程序在运行时需要能找到动态库文件。可执行文件时动态库的调用者。
载入时刻
二者的不同点在于代码被载入的时刻不同。静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
4. 优缺点
相对于动态库,静态库的优点在于直接被链接进可执行程序中,之后,该可执行程序就不再依赖于运行环境的设置了(当然仍然会依赖于 CPU指令集和操作系统支持的可执行文件格式等硬性限制)。
而动