动态链接库DLL是什么?

112 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

为什么不使用静态链接?

  • 静态链接会将编译产生的所有目标文件连同各种库,合并形成一个独立的可执行文件。不需要额外的依赖就可以运行!

  • 静态链接生成文件体积大,相当耗费内存资源,随着软件复杂度的提升,操作系统也越来越臃肿,不同的软件可能包含相同的功能和代码。显然会浪费大量的硬盘空间。

1.jpg

2.jpg

动态链接的优势

这时动态链接的优势就体现出来了,我们可以将需要共享的代码单独提取出来,保存成一个独立的动态链接库,等到程序运行的时候再让他们加载到内存,这样不但可以节省空间,因为同一个模块在内存中只需要保留一份副本,可以被不同的进程所共享,另外因为动态库是很独立的文件,因此我们可以很方便的安装和更新它们!

动态链接优势是单独更新动态库本身,而不用编译其他动态库组件,

动态链接和静态链接的区别

3.jpg

静态链接会将编译产生的所有目标文件连同用到的各种库,合并成一个独立的可执行文件,其中我们会去修正模块间函数的跳转地址,这个过程也叫做重定位。

而动态链接实际上将链接的整个过程推迟到了程序加载的时候,当我们去运行一个程序的时候,操作系统会将程序的数据、代码连同它用到的一系列动态库先加载到内存,并且这个过程是递归的,

4.jpg

比如程序会用到一系列的动态库,而这些动态库又会用到其他的动态库。其中每个动态库的加载地址都是不固定的,操作系统会根据当前地址空间的使用情况为它们动态分配一段内存,当动态库被加载到内存以后,一旦内存地址被确定,我们就可以去修正动态库中的那些函数跳转地址了!

5.jpg

这个过程也是重定位,这些地址在程序加载之前不过只是一堆占位符而已。

6.jpg

动态连接在数据段中专门预留一片区域用来存放函数的跳转地址,它也被叫做全局偏移表GOT(Global Offset Table),里面会存放全局变量和函数的挑战地址,于是在调用函数的时候会首先查表,然后根据表中的地址进行跳转,这些地址在动态库加载的时候会被修改为真正的地址。

7.jpg

查表的过程也很容易实现,由于全局偏移表与代码段的相对位置是固定的,完全可以利用CPU的相对寻址来实现,有了GOT我们可以不用修改代码段,因此代码可以被全局共享!