VC++环境下的动态链接库的开发与应用.doc

上传人:文库蛋蛋多 文档编号:2385675 上传时间:2023-02-17 格式:DOC 页数:34 大小:1.06MB
返回 下载 相关 举报
VC++环境下的动态链接库的开发与应用.doc_第1页
第1页 / 共34页
VC++环境下的动态链接库的开发与应用.doc_第2页
第2页 / 共34页
VC++环境下的动态链接库的开发与应用.doc_第3页
第3页 / 共34页
VC++环境下的动态链接库的开发与应用.doc_第4页
第4页 / 共34页
VC++环境下的动态链接库的开发与应用.doc_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《VC++环境下的动态链接库的开发与应用.doc》由会员分享,可在线阅读,更多相关《VC++环境下的动态链接库的开发与应用.doc(34页珍藏版)》请在三一办公上搜索。

1、目录目录1中文摘要2Abstract2一、概论31.1. 研究背景31.2. 动态链接库的定义31.3. 动态链接库与静态链接库41.3.1. 静态链接库41.3.2. 动态链接库与静态链接库的区别41.4. 动态链接库的优点41.5. 在以下这些情况下,必须使用动态链接库:51.6. Visual C+支持的动态链接库的类型5二、非MFC动态链接库62.1. Non-MFC DLL动态链接库的创建62.1.1. 创建一个Non-MFC Dll工程“MyDll”62.1.2. 代码分析82.2. 声明导出函数92.3. DLL的调用方式102.4. DllMain函数11三、MFC规则动态链接

2、库的创建133.1. 概述133.2. MFC规则DLL分为两类:133.3. MFC规则DLL的创建143.4. MFC规则DLL的调用183.5. 隐式调用22四、MFC扩展动态链接库的创建24 4.1. 概述24 4.3. MFC扩展DLL的加载30五、动态链接库的典型应用315.4. DLL木马36六、参考文献37七、致谢38中文摘要 动态链接库英文为Dynamic Link Library,英文缩写为DLL,是程序运行时由该程序动态链接调用的函数库,是一些函数、数据和类集合成的可执行模块,程序员可以将动态链接库动态地集成到自己的程序中以使用库中的函数、数据和类。开发和应用动态链接库,

3、有助于数据和资源的共享,简化了软件项目的管理。本文主要介绍动态链接库创建、调用方法,及其典型应用。关键词:动态链接库(DLL),非MFC DLL,MFC规则DLL,MFC扩展DLLAbstractDynamic Link Library (DLL) encapsulates the shared resource and codeIn exploring the application based on Windows,the use of DLL technology can greatly save the memoryUsing DLL developing project can si

4、mplify the project management and speed up the explorationThis paper,introducing the implicit and explicit linking of DLL with instances,provides technical support to technicians in exploring and using DLL Key words:Dynamic Link Library (DLL) , Non-MFC DLL ,MFC Regular DLL , MFC Extension DLL一、概论1.1

5、. 研究背景自从微软推出16位的Windows操作系统起,此后每种版本的Windows操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上Windows操作系统中几乎所有的内容都由DLL以一种或另外一种形式代表着,例如显示的字体和图标存储在GDI DLL中、显示Windows桌面和处理用户的输入所需要的代码被存储在一个User DLL中、Windows编程所需要的大量的API函数也被包含在Kernel DLL中。在Windows操作系统中使用DLL有很多优点,最主要的一点是多个应用程序、甚至是不同语言编写的应用程序可以共享一个DLL文件,真正实现了资源共享,大大缩小了应用程序的执行代

6、码,更加有效的利用了内存;使用DLL的另一个优点是DLL文件作为一个单独的程序模块,封装性、独立性好,在软件需要升级的时候,开发人员只需要修改相应的DLL文件就可以了,而且,当DLL中的函数改变后,只要不是参数的改变,程序代码并不需要重新编译。这在编程时十分有用,大大提高了软件开发和维护的效率。既然DLL那么重要,所以搞清楚什么是DLL、如何在Windows操作系统中开发使用DLL是程序开发人员不得不解决的一个问题。本文针对这些问题,通过一个简单的例子,全面地解析了在Visual C+编译环境下编程实现DLL的过程。1.2. 动态链接库的定义动态链接库英文为Dynamic Link Libra

7、ry,英文缩写为DLL,是程序运行时由该程序动态链接调用的函数库,是一些函数、数据和类集合成的可执行模块,程序员可以将动态链接库动态地集成到自己的程序中以使用库中的函数、数据和类。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。多个应用程序可同时访问内存中单个DLL 副本的内容。1.3. 动态链接库与静态链接库1.3.1. 静态链接库静态链接库就是你使用的.lib文件,库中的代码最后需要连接到你的可执行文件中去。静态链接库不同于动态链接库(*.dll),在静态库情况下

8、,函数和数据被编译进一个二进制文件(通常扩展名为*.LIB),Visual C+的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为静态链接,此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。用户在交付最终静态链接库时,只需要提供.lib文件和相应的头文件,不需要再提供库的源代码。在需要使用静态库的工程中,包含相应的头文件,并把.lib文件加入工程中就可以了。1.3.2. 动态链接库与静态链接库的区别动态链接发生在程序运行时,动态链接的函数代码不出现在程序的EXE文件中,它仅仅包含了

9、应用程序运行过程中所调用的DLL函数的一些最基本信息(例如DLL文件位置、函数名等);而静态链接发生在编译时,静态链接的函数代码实际被插入到程序的EXE文件中。1.4. 动态链接库的优点动态链接库随处可见,无论大型系统还是小规模软件,都应用了动态链接库,有效地实现了资源共享。在软件开发中,应用动态链接库具有以下优点:(1)扩展了应用程序的特性;(2)可以用许多种编程语言来编写; (3)简化了软件项目的管理; (4)有助于节省内存; (5)有助于资源共享; (6)有助于应用程序的本地化;(7)有助于解决平台差异。1.5. 在以下这些情况下,必须使用动态链接库:(1)多个应用程序共享代码和数据(2

10、)在各子程序过滤系统消息时必须使用动态链接库(3)设备驱动程序必须是动态链接库(4)在对话框编辑器中使用自己定义的控件,也必须使用动态链接库(5)为了实现应用程序的国际化,往往需要使用动态链接库1.6. Visual C+支持的动态链接库的类型Visual C+支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。(1) 非MFC动态库指不使用MFC类库创建的DLL。Win32 DLL中的导出函数通常使用标准的C接口,这些函数可以被MFC或非MFC应用程序调用。(2) MF

11、C规则DLL MFC规则DLL可以使用MFC来创建,可以导出C风格的函数,但不能导出C+类、成员函数或重载函数。它们可以被MFC或非MFC应用程序调用。但这种类型的DLL不能向应用程序传递MFC对象指针,必须使用MFC扩展DLL。MFC常规DLL按照与MFC的链接方式又分动态链接和静态链接两种。(3) MFC扩展DLL表面上更像应用程序而不像一组函数的集合,因为它可以创建MFC派生类。只能以动态方式与MFC链接,而且只能是使用MFC的动态链接版本的应用程序才可以使用这种DLL。在MFC扩展DLL中,可以由现有的MFC类导出自己的类,然后给应用程序一个扩展的MFC版本。支持C+接口,也就是说,该

12、DLL可以导出整个类,客户可以构造这些类的对象或从这些类进行派生。还可以用于在应用程序和DLL之间传递MFC导出对象。对象的成员函数位于创建对象的模块中,应用程序和它加载的扩展DLL之间可以自如地传递MFC或MFC导出对象的指针。 接下来,我们一起来具体讨论一下以上三种动态链接库的创建方法与调用方法。二、非MFC动态链接库2.1. Non-MFC DLL动态链接库的创建在Visual C+6.0开发环境下,打开File/New/Project选项,可以选择Win32 Dynamic-Link Library或MFC AppWizarddll 来以不同的方式来创建Non-MFC Dll、Regu

13、lar Dll、Extension Dll等不同种类的动态链接库。下面演示以Win32 Dynamic-Link Library方式创建一个简单Non-MFC Dll工程“MyDll”。2.1.1. 创建一个Non-MFC Dll工程“MyDll”(1) 在Visual C+6.0开发环境下,打开File/New/Project选项,选择Win32 Dynamic-Link Library创建一个简单DLL工程,并命名为“MyDll”。图2-1-1 创建Non-MFC Dll工程“MyDll”(2) 在建立的工程中添加lib.h及lib.cpp文件,源代码如下:/* 文件名:lib.h*/#i

14、fndef LIB_H#define LIB_Hextern C int _declspec(dllexport)multi(int x,int y);#endif/* 文件名:lib.cpp*/#include lib.hint multi(int x,int y) return x*y;显然,以上建立的是一个返回两个数的乘积的动态链接库。(3)建立一个与MyDll工程处于同一工作区的应用工程DllCall。图2-1-2 创建应用工程“DllCall”在工程“DllCall”创建源代码文件“DllCall.cpp”,它调用DLL中的函数multi,其源代码如下:#include #inclu

15、de typedef int(*lpmultiFunc)(int,int); /宏定义函数指针类型int main() HINSTANCE hDll; /DLL句柄lpmultiFunc multiFunc; /函数指针hDll = LoadLibrary(.DebugMyDll.dll);if (hDll != NULL) multiFunc = (lpmultiFunc)GetProcAddress(hDll, multi);if (multiFunc != NULL) int result = multiFunc(3,5); /计算3与5的乘积 printf(%dn,result);Fr

16、eeLibrary(hDll);return 0;(4) 编译,运行结果如下:图2-1-3 运行结果 如上图所示,成功返回3*5的结果,表明此NON-MFC DLL创建成功。2.1.2. 代码分析分析上述代码,Mydll工程中的lib.h对函数multi的声明前面添加了_declspec(dllexport)语句。这个语句的含义是声明函数multi为DLL的导出函数。DLL内的函数分为两种:(1) DLL导出函数,可供应用程序调用;(2) DLL内部函数,只能在DLL程序使用,应用程序无法调用它们。现在分析应用工程dllCall 对 DLL 的调用是如何实现的:首先,语句typedef int

17、 ( * lpmultiFun)(int,int)定义了一个与multi函数接受参数类型和返回值均相同的函数指针类型。随后,在main函数中定义了lpmultiFunc的实例multiFunc;其次,在函数main中定义了一个DLL HINSTANCE句柄实例hDll,通过Win32 Api函数LoadLibrary动态加载了DLL模块并将DLL模块句柄赋给了hDll;再次,在函数main中通过Win32 Api函数GetProcAddress得到了所加载DLL模块中函数multi的地址并赋给了multiFunc。经由函数指针multiFunc进行了对DLL中add函数的调用; 最后,应用工程

18、使用完DLL后,在函数main中通过Win32 Api函数FreeLibrary释放了已经加载的DLL模块。从而完成了对dll的调用。通过以上例子分析可得出以下结论:(1)DLL中需以某种特定的方式声明导出函数(或变量、类);(2)应用工程需以某种特定的方式调用DLL的导出函数(或变量、类)。2.2. 声明导出函数DLL中导出函数的声明有两种方式:一是像上述例子一样,在定义函数时使用导出关键字_declspec(dllexport);另外一种方法是在创建DLL文件时使用模块定义文件.def。如以下例子:下面的代码演示了怎样在 .def 文件中将函数multi声明为DLL导出函数(需在MyDll

19、工程中添加lib.def文件):LIBRARY MydllEXPORTSmulti 1def文件的规则为:(1)LIBRARY语句说明.def文件相应的DLL;(2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);(3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行。由此可以看出,例子中lib.def文件的含义为生成名为“MyDll”的动态链接库,导出其中的multi函数,并指定multi函数的序号为1。2.3. DLL的调用方式DLL有两种调用方式:(

20、1) 动态调用在上述的例子中我们看到了由“LoadLibrary-GetProcAddress-FreeLibrary”系统Api提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式,这种调用方式称为DLL的动态调用。 动态调用方式的特点是完全由编程者用 API 函数加载和卸载 DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个 DLL 文件。(2) 静态调用静态调用方式的特点是由编译系统完成对DLL的加载和应用程序结束时 DLL 的卸载。当调用某DLL的应用程序结束时,若系统中还有其它程序使用该 DLL,则Windows对DLL的应用记录减1,直到

21、所有使用该DLL的程序都结束时才释放它。静态调用方式简单实用,但不如动态调用方式灵活。如以下例子所示:将编译MyDll工程所生成的.lib和.dll文件拷入dllCall工程所在的路径,图2-3-1 添加MyDll.lib和MyDll.dll文件在dllCall源文件下执行下列代码:#include #pragma comment(lib,MyDll.lib)/.lib文件中仅仅是关于其对应DLL文件中函数的重定位信息extern C _declspec(dllimport) multi(int x,int y);int main(int argc, char* argv )int resul

22、t = multi(3,5);printf(静态调用结果:%dn,result);return 0;编译运行,运行结果如下:图2-3-2 运行结果由上述代码可以看出,静态调用方式的顺利进行需要完成两个动作:(1) 告诉编译器与DLL相对应的.lib文件所在的路径及文件名,#pragma comment(lib,MyDll.lib)就是起这个作用。程序员在建立一个DLL文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了DLL 导出函数的符号名及序号(并不含有实际的代码)。在应用程序里,.lib文件将作为DLL的替代文件参与编译。(2) 声明导入函数,extern C _declsp

23、ec(dllimport)multi(int x,int y)语句中的_declspec(dllimport)发挥这个作用。静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE 文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在 EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL 函数的动态链接。这样,EXE将能直接通过函数名调用D

24、LL的输出函数,就象调用程序内部的其他函数一样。2.4. DllMain函数Windows在加载DLL的时候,需要一个入口函数,就如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样。在前面的例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。根据编写规范,Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。这个函数并不属于导出

25、函数,而是DLL的内部函数。这意味着不能直接在应用工程中引用DllMain函数,DllMain是自动被调用的。以下是一个DllMain函数的例子BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)switch (ul_reason_for_call)case DLL_PROCESS_ATTACH:printf(nprocess attach of dll);break;case DLL_THREAD_ATTACH:printf(nthread attach of dll);brea

26、k;case DLL_THREAD_DETACH:printf(nthread detach of dll);break;case DLL_PROCESS_DETACH:printf(nprocess detach of dll);break;return TRUE;DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DLLMain函数也被调用,ul_reason_for_call指明了被调用的原因。原因共有4种,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和THREAD_DETACH,以switch语句列出。分析DllMain的

27、函数头BOOL APIENTRY DllMain( HANDLE hModule, WORD ul_reason_for_call, LPVOID lpReserved )APIENTRY被定义为_stdcall,它意味着这个函数以标准Pascal的方式进行调用,也就是WINAPI方式;进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。三、MFC规则动态链接库的创建3.1. 概

28、述(1) MFC规则DLL,顾名思义,可以在这种DLL的内部使用MFC;(2) 它是规则的,意味着它不同于MFC扩展DLL,在MFC规则DLL的内部虽然可以使用MFC,但是其与应用程序的接口不能是MFC。而MFC扩展DLL与应用程序的接口可以是MFC,可以从MFC扩展DLL中导出一个MFC类的派生类。MFC规则DLL能够被所有支持DLL技术的语言所编写的应用程序调用,当然也包括使用MFC的应用程序。在这种动态连接库中,包含一个从CWinApp继承下来的类,DllMain函数则由MFC自动提供。3.2. MFC规则DLL分为两类:(1) 静态链接到MFC 的规则DLL静态链接到MFC的规则DLL

29、与MFC库(包括MFC扩展 DLL)静态链接,将MFC库的代码直接生成在.dll文件中。在调用这种DLL的接口时,MFC使用DLL的资源。因此,在静态链接到MFC 的规则DLL中不需要进行模块状态的切换。使用这种方法生成的规则DLL其程序较大,也可能包含重复的代码。(2) 动态链接到MFC 的规则DLL动态链接到MFC 的规则DLL 可以和使用它的可执行文件同时动态链接到 MFC DLL 和任何MFC扩展 DLL。在使用了MFC共享库的时候,默认情况下,MFC使用主应用程序的资源句柄来加载资源模板。这样,当DLL和应用程序中存在相同ID的资源时(即所谓的资源重复问题),系统可能不能获得正确的资

30、源。因此,对于共享MFC DLL的规则DLL,我们必须进行模块切换以使得MFC能够找到正确的资源模板。我们可以在Visual C+中设置MFC规则DLL是静态链接到MFC DLL还是动态链接到MFC DLL。如下图,依次选择Visual C+的project - Settings - General菜单或选项,在Microsoft Foundation Classes中进行设置。图 3-2-1 设置动态/静态链接MFC DLL3.3. MFC规则DLL的创建下面一步步讲述使用MFC向导创建一个简单的MFC规则DLL的过程。 (1)首先在Visual C+6.0开发环境下,打开File/New/

31、Project选项,选择MFC AppWizard(dll)创建一个简单DLL工程,并命名为“regularDll”。图 3-3-1 创建MFC规则DLL点击“确定”进入如下图所示的对话框,选择“动态链接库和MFC静态链接”图 3-3-2 创建MFC规则DLL点击“完成”按钮完成向导。(2)在工程中添加一个对话框,并设计该对话框。图 3-3-3 创建对话框为该对话框新建一个类CDllDialog,图 3-3-4 新建类CDllDialog为对话框上的按钮“MFC Regualr Dll”添加消息响应函数,图 3-3-5 添加消息响应函数并添加以下代码:void CDllDialog:OnBut

32、ton1() / TODO: Add your control notification handler code hereMessageBox( MFC Regular DLL );在RegularDll.cpp 的最后,添加MFC规则DLL接口函数。extern C _declspec(dllexport) void ShowDlg(void) AFX_MANAGE_STATE(AfxGetStaticModuleState();CDllDialog dllDialog;dllDialog.DoModal();图 3-3-6 添加MFC规则DLL接口函数在RegularDll.cpp 的前

33、面,添加 #include DllDialog.h图 3-3-7 添加MFC规则DLL接口函数完成上述步骤后,就可以编译并生成Dll文件了。图 3-3-8 添加MFC规则DLL接口函数 3.4. MFC规则DLL的调用(1)首先,创建一个基于MFC的单文档应用程序“CallRegDll”。图 3-4-1 创建MFC的单文档应用程序CallRegDll(2)添加一个菜单项“CallRegDll”。图 3-4-2 添加一个菜单项(3)在视类对该菜单项添加消息响应函数,函数代码如下:void CCallRegDllView:OnRegdll() / TODO: Add your command ha

34、ndler code heretypedef void (*lpFun)(void);HINSTANCE hDll=NULL; /DLL句柄hDll = LoadLibrary(RegularDll.dll); if(hDll!=NULL) lpFun pShowDlg = (lpFun)GetProcAddress(hDll,ShowDlg); if ( pShowDlg!=NULL) pShowDlg(); else MessageBox(DLL中函数寻找失败); else MessageBox( 没有找到相应的dll ); (4)编译并运行程序。点击菜单项,会弹出如下界面:图 3-4-3

35、 运行结果(5)将RegularDll.dll和复制到RegularDll.lib 复制到CallRegDll工程 的debug目录下。图 3-4-4 复制RegularDll.lib 和RegularDll.dll再次编译,运行程序,结果如下:图 3-4-5 运行结果3.5. 隐式调用上述例子中给出的是显式调用的方式,我们也可以在EXE程序中隐式调用MFC规则DLL。(1) 将DLL工程生成的.lib文件和.dll文件拷入当前工程所在的目录。图 3-4-6 添加.lib文件和.dll文件(2) 并在CCallRegDllView.cpp文件 的顶部添加以下代码:#pragma comment

36、(lib,RegularDll.lib) /extern C _declspec(dllimport) void ShowDlg(void); /(3) 把消息响应函数CCallRegDllView:OnRegDll()修改为以下:void CCallRegDllView:OnRegDll() / TODO: Add your command handler code here ShowDlg(); (4) 编译运行程序,同样能得到正确的结果。图 3-4-7 运行结果四、MFC扩展动态链接库的创建4.1. 概述MFC扩展DLL与MFC规则DLL的相同点在于在两种DLL的内部都可以使用MFC类库

37、,其不同点在于MFC扩展DLL与应用程序的接口可以是MFC的。MFC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC库类中派生出可重用的类。MFC扩展DLL使用MFC 动态链接库版本,因此只有用共享MFC 版本生成的MFC 可执行文件(应用程序或规则DLL)才能使用MFC扩展DLL。MFC规则DLL被MFC向导自动添加了一个CWinApp的对象,而MFC扩展DLL则不包含该对象,它只是被自动添加了DllMain 函数。对于MFC扩展DLL,开发人员必须在DLL的DllMain函数中添加初始化和结束代码。总结三种DLL对DllMain入口函数的不同处理方式,可得出下表:DLL类

38、型入口函数非 MFC DLL编程者提供DllMain函数MFC规则 DLLCWinApp对象的InitInstance 和 ExitInstanceMFC扩展 DLLMFC DLL向导生成DllMain 函数对于MFC扩展DLL,系统会自动在工程中添加如下表所示的宏,这些宏为DLL和应用程序的编写提供了方便。像AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA这样的宏,在DLL和应用程序中将具有不同的定义,这取决于_AFXEXT宏是否被定义。这使得在DLL和应用程序中,使用统一的一个宏就可以表示出输出和输入的不同意思。宏定义AFX_CLASS_IMPORT_decls

39、pec(dllexport)AFX_API_IMPORT_declspec(dllexport)AFX_DATA_IMPORT_declspec(dllexport)AFX_CLASS_EXPORT_declspec(dllexport)AFX_API_EXPORT_declspec(dllexport)AFX_DATA_EXPORT_declspec(dllexport)AFX_EXT_CLASS#ifdef _AFXEXTAFX_CLASS_EXPORT#elseAFX_CLASS_IMPORTAFX_EXT_API#ifdef _AFXEXTAFX_API_EXPORT#elseAFX_

40、API_IMPORTAFX_EXT_DATA#ifdef _AFXEXTAFX_DATA_EXPORT#elseAFX_DATA_IMPORT4.2. MFC扩展DLL导出MFC派生类在下述例子中,我们将新建一个名为“ExtDll”的MFC扩展DLL工程,在这个DLL中导出一个对话框类,这个对话框类派生自MFC类CDialog。图 4-2-1 创建MFC扩展DLL图 4-2-2 创建MFC扩展DLL使用MFC向导生成MFC扩展DLL时,系统会自动添加如下代码:static AFX_EXTENSION_MODULE ExtDllDLL = NULL, NULL ;extern C int API

41、ENTRYDllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )/ Remove this if you use lpReservedUNREFERENCED_PARAMETER( lpReserved );/说明:lpReserved是一个被系统所保留的参数,对于隐式链接是一个非零值,对于显式链接值是零if (dwReason = DLL_PROCESS_ATTACH)TRACE0( EXTDLL.DLL Initializing!n );/ Extension DLL one-time initialization

42、if ( !AfxInitExtensionModule( ExtDllDLL, hInstance )return 0;/ Insert this DLL into the resource chainnew CDynLinkLibrary( ExtDllDLL );else if (dwReason = DLL_PROCESS_DETACH)TRACE0( EXTDLL.DLL Terminating!n );/ Terminate the library before destructors are calledAfxTermExtensionModule( ExtDllDLL );re

43、turn 1; / ok代码分析如下:(1)上述代码完成MFC扩展DLL的初始化和终止处理;(2)初始化期间所创建的 CDynLinkLibrary 对象使MFC扩展 DLL 可以将 DLL中的CRuntimeClass 对象或资源导出到应用程序;(3)AfxInitExtensionModule函数捕获模块的CRuntimeClass 结构和在创建 CDynLinkLibrary 对象时使用的对象工厂(COleObjectFactory 对象);(4)AfxTermExtensionModule函数使 MFC 得以在每个进程与扩展 DLL 分离时(进程退出或使用AfxFreeLibrary卸

44、载DLL时)清除扩展 DLL;(5)第一条语句static AFX_EXTENSION_MODULE ExtDllDLL = NULL, NULL ;定义了一个AFX_EXTENSION_MODULE类的静态全局对象,AFX_EXTENSION_MODULE的定义如下:struct AFX_EXTENSION_MODULEBOOL bInitialized;HMODULE hModule;HMODULE hResource;CRuntimeClass* pFirstSharedClass;COleObjectFactory* pFirstSharedFactory; 在资源编辑器中添加一个如下

45、图所示的对话框,并使用MFC类向导为其添加一个对应的类CExtDialog,系统自动添加了ExtDialog.h和ExtDialog.cpp两个头文件。图 4-2-3 添加对话框图 4-2-3 添加对话框类修改ExtDialog.h中CExtDialog类的声明为:class AFX_EXT_CLASS CExtDialog : public CDialogpublic:CExtDialog( CWnd* pParent = NULL );enum IDD = IDD_DLL_DIALOG ;protected:virtual void DoDataExchange( CDataExchange* pDX );DECLARE_MESSAGE_MAP();这其中最主要的改变是我们在class AFX_EXT_CLASS CExtDialog语句中添加了“AFX_EXT_CL

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号