(本文针对的是使用MFC下的DLL)
MFC规则DLL
何为规则DLL(Regular DLL)
(1)该DLL是基于MFC的,可以在这种DLL内部使用MFC。
(2)该DLL是"规则"的,它不同于"MFC扩展DLL",在规则DLL中内部虽然是可以使用MFC,但是规则DLL的接口应该不能是基于MFC的。而MFC扩展DLL与应用程序接口可以是MFC,可以从MFC扩展dll
中导出一个MFC的派生类。
Regular DLL能够被所有支持DLL技术的语言所编写的应用程序调用,当然也包括使用MFC的应用程序。在这种动态连接库中,包含一个从CWinApp
继承下来的类,DllMain
函数则由MFC自动提供。
共享MFC DLL(或MFC扩展DLL)的规则DLL涉及到HINSTANCE句柄问题,HINSTANCE句柄对于加载资源特别重要。EXE和DLL都有其自己的资源,而且这些资源的ID可能重复,应用程序需要通过资源模块的切换来找到正确的资源。如果应用程序需要来自于DLL的资源,就应将资源模块句柄指定为 DLL的模块句柄;如果需要EXE文件中包含的资源,就应将资源模块句柄指定为EXE的模块句柄。(解释:EXE模块在进程虚拟空间中的起始地址 。 进程本身的模块句柄一般为0x400000 , 而DLL模块的缺省句柄为0x10000000 。 如果程序同时加载了多个DLL,则每个DLL模块都会有不同的 HINSTANCE 。 应用程序在加载DLL时对其进行了重定位。)
模块的切换有三种方式:
-
在DLL函数中调用
AFX_MANAGE_STATE(AfxGetStaticModuleState());
void ShowDlg(void) { //在函数开始处变更,在函数结束时恢复 //将AFX_MANAGE_STATE(AfxGetStaticModuleState()); //作为接口函数的第一条语句进行模块状态切换 AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框 dlg.DoModal(); }
-
在DLL函数中调用
AfxGetResourceHandle();
AfxGetResourceHandle
用于获取当前资源模块句柄,而AfxSetResourceHandle
则用于设置程序目前要使用的资源模块句柄。我们将DLL中的接口函数
ShowDlg
改为:void ShowDlg(void) { //方法2的状态变更 HINSTANCE save_hInstance = AfxGetResourceHandle()