静态链接库和动态链接库

时间:2022-04-10 15:50:23
  • 静态链接库
  • 动态链接库

静态链接库

windows下表示方法: .lib
linux下表示方法: .a

静态库是一个或者多个算法或者函数实现文件的打包,把所有编译而成的文件生成静态链接的函数库(static lib),这个过程称为Archive,即合并到一起。然后将相关的对象文件(object file)与牵涉到的函数库链接合成一个可执行文件(executable)。
程序运行的时,与函数库没有什么关系,等于将所需要的函数已经拷贝到了可执行文件里。

动态链接库

window下表示方法: .dll
linux下表示方法: .so

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序调用相同的库,那么在内存里只需要有一份该共享的实例,规避了空间浪费问题。
动态库是一组源代码的模块,每个模块包含一些可供应用程序或者其他动态库调用的函数,在应用程序调用一个动态库里面的函数的时候,操作系统会将动态库的文件映像映射到进程的地址空间中,这样进程中所有的线程就可以调用动态库中的函数了

动态库加载完成后,这个时候动态库对于进程中的线程来说只是一些被放在地址进程空间附加的代码和数据,操作系统为了节省内存空间,同一个动态库在内存中只有一个,也就是说如果你的的两个应用程序都需要加载function.dll,那么操作系统也只会加载一次function.dll到内存中

因为代码段在内存中的权限都是为只读的,所以当多个应用程序加载同一个动态库的时候,不用担心应用程序会修改动态库的代码段。当线程调用动态库的一个函数,函数会在线程栈中取得传递给他的参数,并使用线程栈来存放他需要的变量,动态库里的函数创建的任何对象都为调用线程或者调用进程拥有,动态库不会拥有任何对象,也就是说如果动态库中的一个函数调用了VirtualAlloc,系统会从调用进程的地址空间预定地址,即使撤销了对动态库的映射,调用进程的预定地址依然会存在,直到 用户取消预定或者进程结束

混淆概念“导入库”

动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己调入动态库文件,然后再手工获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。

例如opencv库里

静态链接库和动态链接库

lib文件夹里放的是导入库尾缀是.lib
staticlib文件夹里放的是静态链接库尾缀也是.lib
两者的大小是不一样的(如下两图对比),对于导入库,其实际的执行代码位于动态库中,导入库只包含了地址符表等,确保程序找到对于函数的一些基本地址信息。
可以观察下面两图:

静态链接库.lib

静态链接库和动态链接库

导入库里的.lib

静态链接库和动态链接库

分享推送

另一篇关于静态库与动态库的优秀博文: