Windows核心编程(十八)DLL基础

本文详细介绍了DLL(动态链接库)在Windows系统中的作用和应用,包括Kernel32.dll、User32.dll和GDI32.dll等关键DLL的功能。DLL的主要好处在于代码复用、内存节省和资源分享,同时也可用于特殊目的如钩子函数。文章阐述了DLL的构造过程,从创建头文件、编译源文件到链接生成DLL和LIB文件,以及如何在可执行模块中隐式链接DLL。最后,讨论了DLL的加载顺序和搜索路径,以及防止DLL伪造的安全措施。
摘要由CSDN通过智能技术生成

1、DLL全称dynamic linking library,即动态链接库。广泛应用于windows及其他系统中,windows中所有API都包含在DLL中。三个最重要的DLL是:

Kernel32.dll:包含的函数用来管理内存、进程及线程。

User32.dll:用来执行与用户界面相关的任务,如创建窗口和发送消息。

GDI32.dll:用来绘制图像和显示文字。


2、使用dll的好处:

1)扩展了应用程序的特性。DLL可以被动态地载入到进程的地址空间中。

2)简化了项目管理,可以让不同的开发团队管理不同的模块。

3)有助于节省内存。一个dll可被多个程序共享。多个程序调用同一个dll内的同一个函数时,系统却只需将该dll加载一次。

4)促进资源共享。

5)促进了本地化。可以使应用程序只包含代码但不包含用户界面组件。

6)有助于解决平台间差异。使用延迟加载机制,程序仅仅加载需要的函数,使程序可以在老版本的系统中运行,可不是在某些函数不被兼容时拒绝运行。

7)可以用于特殊目的。如钩子函数等等。


3、DLL通常由一组可供任何应用程序使用的独立函数组成,通常没有用来处理消息循环或创建窗口的代码。DLL只不过是一组源代码模块。在所有的源文件编译完成之后,就会对DLL进行链接。在创建DLL时候,我们必须给链接器指定/DLL开关,这个开关用来识别DLL,以区分应用程序。


4、在应用程序可以调用dll中的函数之前,必须将dll载入进程地址空间,之后进程中所有的线程就可以使用该DLL中的函数了。可以通过两种方式实现:一种是通过隐式载入时链接。另一种是显式运行时链接。接下来主要介绍隐式链接的过程。显式链接在DLL高级技术中介绍。


5、当线程调用DLL中的一个函数的时候,该函数会在线程栈中取得传给他的参数,并使用线程栈来存放它需要的局部变量。此外,该DLL中的函数创建的任何对象都为调用线程或调用进程所拥有,DLL绝对不会拥有任何对象。

我们必须理解:一个地址空间是由一个可执行模块和多个DLL模块构成的,这些模块中,有些可能会链接到C/C++运行库的静态版本和DLL版本。


6、在载入之前,必须要构造DLL文件。下面我们来谈谈dll的构造过程。

1)创建一个头文件。该头文件包含我们想要在dll中导出的函数原型、结构以及符号。构建dll时所有的源文件都必须包含该头文件。另外可执行文件也需要该头文件。

2)创建C/C++源文件来实现dll模块中想要导出的函数和变量。该源文件在构造可执行文件时并需要该源文件。

3)编译器对每个源文件处理,并分别产生一个obj文件。

4)链接所有的obj模块。产生独立的dll映像文件。该文件在构建可执行文件时被使用。

5)如果dll文件中输出了至少一个函数或变量,链接器还会生成lib文件。他只是列出了所有被导出的函数和变量的符号名。为了构建可执行模块,在可执行模块代码链接时,该文件也是必需的。


7、一旦构建了DLL模块,我们就可以构建可执行模块:

1)所有源文件中包含dll开发人员创建的dll的头文件。

2)创建源文件。包含所有函数和变量。代码中可以引用dll的函数和变量。

3)为每个源文件产生obj文件。

4)将所有obj文件链接,生成独立的可执行映像文件。该文件中包含所有二进制代码预计全局静态变量。还包含一个导入段,列出了他需要的dll模块的名称,以及可执行文件的二进制代码从中引用的函数和变量的符号名。


8、执行:

加载程序为新建进程申请一个地址空间区域,然后将可执行模块映射到地址空间中。加载程序接着解析可执行模块的导入段,对导入段中每个导入函数所在的dll,加载程序会在系统中对dll模块进行定位,并将该dll映射到进程的地址空间中。如果dll需要从其他dll导入变量或函数,其他dll也会被映射到进程地址空间,执行类似的操作。将所有dll映射到进程地址空间后,就可以开始运行了。


9、构建DLL模块

dll中通常只包含函数或变量,并不包含消息循环或创建窗口的代码,因此创建dll文件相对容易。要注意在实际使用中,为了去掉代码的抽象层,应该避免从dll中导出变量。

首先应该创建一个包含想要导出的变量或函数声明的头文件。所有dll的源文件都应该包含这个文件,所有需要导入这些函数和变量的可执行模块的源文件也要包含该文件。

例子:   

[cpp]  view plain copy
  1.  //Mydll.h   dll头文件。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值