静态库 共享库 静态链接 动态链接
库,是一种封装机制,简单说是把所有的源代码编译成目标代码后打成的包.库的开发者除了提供库的目标代码外,还提供一系列的头文件,头文件中就包含了库的接口,库分为静态库(static library)和共享库(share library)。在Linux中静态库以一种存档(archive)的特殊文件格式存放在磁盘中,由后缀.a标识;共享库通常用.so后缀来表示。win下分别是.lib和.dll
Linux ld程序这样的静态连接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出。静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来,“静态库的链接可以使用静态链接,共享库也可以使用这种方法链接导入库”。在链接静态库的时候,链接器只拷贝静态库里被应用程序引用的目标模块,但这种拷贝是完整的拷贝,所以在链接成功后,程序运行不需要静态库的参与。对于一个运行巨多进程的系统上,每个进程都将引用到的相同库函数复制到各自的文本段中,这将是对内存资源的极大浪费。静态链接静态库的优点:代码的装载速度快,执行速度也比较快。
共享库的两种链接方法:
(1) 装载时动态链接(Load-time Dynamic Linking):这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数,编译时在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中,其主要目的是便于代码共享。所有引用该库的可执行目标文件共享这个.so文件中的代码和数据(存储器映射共享对象到共享区域),而不是像静态库的内容那样被拷贝和嵌入到引用他们的可执行文件文本段或数据段中。
(2) 运行时动态链接(Run-time Dynamic Linking):这种方式是指在编译之前并不知道将会调用哪些DLL函数,完全是在运行过程中根据需要决定应调用哪个函数,并用LoadLibrary和GetProcAddress动态获得DLL函数的入口地址。
在运行的时候,共享库可以加载到任意的存储器地址,并和一个在存储器中的部分链接的可执行目标文件链接起来。这个过程称为动态链接,由动态链接器来执行。动态链接的时候,程序往往并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序。在运行时(runtime/execution-time),某个程序在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了,如果有,则让其共享那一个拷贝;只有没有才链接载入。
动态链接共享库的优点:(1)更加节省内存;(2)库文件与可执行目标文件独立,只要输出接口不变,更换库文件不会对可执行目标文件造成任何影响,因而极大地提高了可维护性和可扩展性。
说明:Linux下进行链接的缺省操作是先考虑动态链接库,即如果同时存在静态和共享库,不特别指定的话,将与共享库相连接。
共享库使得可执行目标文件中不再需要包含公用的库例程,而只需在所有进程都可以引用的存储区中维护这种库例程的一个副本。程序第一次执行或者第一次调用某个库函数时,用动态链接方式将程序与共享库函数想链接。这减少了每个可执行目标文件的大小,但增加了一些运行时间开销。这种时间开销发生在该程序第一次被执行时,或者每个共享库函数第一次被调用时。共享库的另一个优点是可以用库函数的新版本代替老版本,而无需对该使用该库的程序重新连接标记(假定接口没有发生改变)
动态链接库的应用举例
1、所有的Windows系统调用(Windows API函数)都是以动态链接库的形式提供的。我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。与这些动态库相对应的导入库分别为kernel32.lib、user32.lib和gdi32.lib。
2、软件的自动更新。Windows应用的开发者常常利用动态链接库来分发软件更新。他们生成一个动态库的新版本,然后用户可以下载,并用它替代当前的版本。当然,新、旧版本动态库的输出接口(即导出函数)必须一致。下一次用户运行应用程序时,应用将自动链接和加载新的动态库。
3、软件插件技术。许多Windows应用软件都支持插件扩展方式,如IE浏览器、Photoshop、Office等等。插件在本质上都是动态库。
4、可扩展的Web服务器。
5、每个Windows驱动程序在本质上都是动态链接库。