2024年4月3日发(作者:)

主题:DLL是Windows最重要的组成要素,Windows中的许多新功能、新特性都是通过

DLL来

实现的,因此掌握它、应用它是非常重要的。

动态链接库不仅可以作为一个运行模块,包括函数代码,而且可以包含程序以外的任何数据

或资源(位图、图标等等)。动态链接库就是给应用程序提供函数或者资源。

DLL是一种磁盘文件(通常带有DLL扩展名),它由全局数据、服务函数和资源组成,

在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。在运行时,只有当EXE

程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。每个进程都

制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声

明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。

DLL文件中包含一个导出函数表。这些导出函数由它们的符号名和称为标识号的整数与外

界联系起来。

导入导出函数:

在DLL代码中,必须像下面这样明确声明导出函数:

__declspec(dllexport) int MyFunction(int n);

但也可以在模块定义(DEF)文件中列出导出函数,不过这样做常常引起更多的麻烦。在应用

程序方面,要

求像下面这样明确声明相应的输入函数:

__declspec(dllimport) int MyFuncition(int n); (这是隐式链接dll)

仅有导入和导出声明并不能使应用程序内部的函数调用链接到相应的DLL文件上。应用程

序的项目必须为

链接程序指定所需的输入库(LIB文件)。而且应用程序事实上必须至少包含一个对DLL

函数的调用。

隐式链接和显式链接dll

显式:typedef double(SQRTPROC)(double);

HINSTANCE hInstance; //设置全局变量用于存储DLL句柄

SQRTPROC* pFunction; 第二个变量ShowMe是指向DLL,库中函数的指针

VERIFY(hInstance=::LoadLibrary("c://winnt//system32//"));

VERIFY(pFunction=(SQRTPROC*)::GetProcAddress(hInstance,"SquareRoot"));

double d=(*pFunction)(81.0);//调用该DLL函数

隐式: 程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件

中导出符号相

匹配,这些符号或标识号进入到生成的EXE文件中.

隐式链接和显式链接dll的区别:

在隐式链接方式中,所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加

载在到内存中;但

如果采用显式链接方式,程序员可以决定DLL文件何时加载或不加载。

DLLMAIN函数:

当Windows加载DLL模块时调用这一函数。系统首先调用全局对象的构造函数,然后调用

全局函数DLLMain。

DLLMain函数不仅在将DLL链接加载到进程时被调用,在DLL模块与进程分离时(以及其

它时候)也被调用。

进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识。进程自己还有一

个HINSTANCE句柄。所

有这些模块句柄都只有在特定的进程内部有效,它们代表了DLL或EXE模块在进程虚拟空

间中的起始地址。

寻找DLL的路径:

Windows将遵循下面的搜索顺序来定位DLL:

1. 包含EXE文件的目录,

2. 进程的当前工作目录,

3. Windows系统目录,

4. Windows目录,

5. 列在Path环境变量中的一系列目录。

要点:

一:DLL文件的省缺名称是与工程名一致的(也是在.DEF文件中LIBRARY 之后的名字),不

要试图在制作完毕之后通

过简单的修改.DLL文件的文件名来改变它,这会导致使用该DLL的应用程序错误.

DLL中定义有两种函数:

导出函数(exportfunction): 可以被其他模块调用

内部函数(internalfunction): 只能在DLL内部使用

基于MFC的DLL不适用与制作读取二进制文件的DLL (不易移植,无法正确读取与DOS

应用程序共享的二进制文件)