动态链接库DLL的通俗理解

时间:2022-12-18 09:36:53

今天主要布置了一个任务要求写一个ocx控件,是用VC开发,虽然一直以来都是用VC写程序,但是使用到的功能仅仅是写一个小程编译运行,连链接都省去了,因为所有的功能都在一个文件里面就省去了链接这一步,所以写个这个什么ocx空间也只能是从零开始,主管给了几个DLL文件和说明文档,在电脑C盘里面看见过许多DLL为后缀的文件,但是不知道是什么东西也没有去了解过,现在要用了,这篇文章就给大家介绍一下我对DLL的了解,我是菜鸟准备入门,前辈勿喷。首先看一百度百科上怎么说:


DLL文件又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

在 Windows操作系统中,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。这有助于促进代码重用和内存的有效使用。


通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。例如,一个记账程序可以按模块来销售。可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。
此外,可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。例如,您可能具有一个工资计算程序,而税率每年都会更改。当这些更改被隔离到 DLL 中以后,您无需重新生成或安装整个程序就可以应用更新。

常见种类编辑
Windows操作系统中的一些作为 DLL 实现的文件
•ActiveX 控件 (.ocx) 文件
ActiveX控件的一个示例是日历控件,它使您可以从日历中选择日期。
•控制面板 (.cpl) 文件
.cpl 文件的一个示例是位于控制面板中的项。每个项都是一个专用 DLL。
•设备驱动程序(.drv) 文件
设备驱动程序的一个示例是控制打印到打印机的打印机驱动程序。”

我的理解:

DLL的英文全称是Dynamic Link Library,中文全称是动态链接库,动态链接库与之对应的就是静态链接库了,首先我们来了解一下什么静态链接,我们都知道我们在运行一个C语言程序的时候要经过预处理,编译,汇编,链接然后才能运行,预处理做的东西比较简单,比如说把把所有的宏定义展开,去掉注释,处理一些条件预编译指令等这些比较基础的工作,然后开始编译,编译后生成汇编代码,然后汇编,汇编之后生成的即使机器码了,也即是二进制文件,但是这个时候各个文件生成的汇编文件时相互独立的,main文件生成main文件的二进制文件,其他模块生成其他模块对应的二进制文件,尽管互相之间存在调用的关系,但此时彼此还是独立的,接下来的工作就是链接了,链接顾名思义就是把独立的文件通过他们之间的关系连接起来,我们可以这样理解,比如在main函数里面调用到另外一个文件的A函数,在main函数运行的过程中肯定有个跳转指令要跳转到A函数,在链接之前这个跳转地址还是未知数,连接完之后就把A的地址填充到main函数中对应的位置,这就完成了main文件和包换A函数模块的连接,这只是简单的举例,具体的实现过程是相当复杂的。链接过后形成的可执行文件差不多就是把汇编后的所有文件通过一定的方式(考虑到内存对齐等因素)组合在一起了。这是静态链接的大致过程,从中可以看出静态链接一个特点,就是链接完了之后要是修改了其中的某一个模块,整个程序就得重新链接一遍,这样对于程序的修改和维护都是十分麻烦和不方便的,静态链接还有一个缺点即使容易浪费磁盘空间,比如说有个B模块被10其他模块调用,在链接的时候B模块就要被十次拷贝到10个模块中,如果B模块的大小是1M的话,那么B模块总要就要占用10M的磁盘空间,对于一些大型项目动则几百个几千个模块的话,磁盘空间的占用可想而知,这个时候动态链接就孕育而生,很好的解决了静态链接的几个问题。

百度百科的解释中我们可以知道,链接这个过程在程序运行的时候才会被进行,我们来看看动态链接是如何解决静态链接的几个缺点的:

首先是磁盘空间占用,如果B模块10个其他模块调用,那么在运行的时候会把B模块拷贝到磁盘空间,当其余10个模块运行被加载到磁盘空间的时候,这个时候要做的仅仅是把和唯一的B模块连接起来就可以的了,从我们之前的解释可以看出,仅仅是把10模块跳转指令对应的位置填充为B模块在内存中的位置就可以了,这样B模块仅仅只占用了1M的内存空间,极大地提高了内存的利用率。
程序的修改和升级,如果修改B模块不会影响其他模块,不用再重新编译。
程序的可扩展性和兼容性,程序只要在前期指定好某些接口的规则,后期在扩展的之后只要按照这个规则编写动态链接库就可以了。

对程序和动态链接库的链接工作是由动态连接器来完成的,因为在运行的时候才链接因此在性能现在不如静态链接会,会损失一部分的性能,这个问题可以通过一些优化工作来提高。据估算这个损失的值大概在5%一下。这点性能用来换取程序在空间上的节省和程序构建和升级时的灵活性,是相当值得的。

对于DLL的理解就先写到这里,日后如果再用到再给大家写一篇具体的实现过程。

参考《程序员的自我修养——链接、装载与库》(可下载)