MFC教程(9)-- MFC的进程和线程(2)
2010-03-25 20:35:05 来源:WEB开发网动态链接的规则DLL的模块状态的实现
在本节中,动态链接到MFC DLL(定义了_AFXDLL)的规则DLL在下文简称为规则DLL。
(1)规则DLL的模块状态的定义
规则DLL有自己的模块状态_afxModuleState,它是一个静态变量,定义如下:
static _AFX_DLL_MODULE_STATE afxModuleState;
_AFX_DLL_MODULE_STATE的基类是AFX_MODULE_STATE。
在前面的模块状态切换中提到的AfxGetStaticModuleState函数,其定义和实现如下:
_AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState()
{
AFX_MODULE_STATE* pModuleState = &afxModuleState;
return pModuleState;
}
它返回规则DLL的模块状态afxModuleState。
规则DLL的内部函数使用afxModuleState作为模块状态;输出函数在被调用的时候首先切换到该模块状态,然后进一步处理。
(2)规则DLL的模块状态的初始化
从用户角度来看,动态链接到MFC DLL的规则DLL不需要DllMain函数,只要提供CWinApp对象即可。其实,MFC内部是在实现扩展DLL的方法基础上来实现规则DLL的,它不仅为规则DLL提供了DllMain函数,而且规则DLL也有扩展DLL模块状态controlDLL。
顺便指出,和扩展DLL相比,规则DLL有一个CWinApp(或其派生类)应用程序对象和一个模块状态afxModuleState。应用程序对象是全局对象,所以在进入规则DLL的DllMain之前已经被创建,DllMain可以调用它的初始化函数InitInstance。模块状态afxModuleState是静态全局变量,也在进入DllMain之前被创建,DllMain访问模块状态时得到的就是该变量。扩展DLL是没有CWinApp对象和模块状态的,它只能使用应用程序或者规则DLL的CWinApp对象和模块状态。
由于核心MFC DLL的DllMain被调用的时候,访问的必定是应用程序的模块状态,要把核心DLL的扩展模块状态链接到规则DLL的模块状态中,必须通过规则DLL的DllMain来实现。
规则DLL的DllMain(MFC内部实现)把参数1表示的模块和资源句柄通过AfxWinInit函数保存到规则DLL的模块状态中。顺便指出,WinMain也通过AfxWinInit函数把资源和模块句柄保存到应用程序的模块状态中。
然后,该DllMain还创建了一个CDynLinkLibrary对象,把核心MFC DLL的扩展模块 coreDLL链接到本DLL的模块状态afxModuleState。
接着,DllMain得到自己的应用程序对象并调用InitInstance初始化。
之后,DllMain创建另一个CDynLinkLibrary对象,把本DLL的扩展模块controlDLL链接到本DLL的模块状态afxModuleState。
(3)使用规则DLL的应用程序可不需要CwinApp对象
规则DLL的资源等是由DLL内部使用的,不存在资源或者CRuntimeClass类输出的问题,这样调用规则DLL的程序不必具有模块状态,不必关心规则DLL的内部实现,不一定需要CwinApp对象,所以可以是任意Win32应用程序,
还有一点需要指出,DllMain也是规则DLL的入口点,在它之前,调用DllMain的RawDllMain已经切换了模块状态,RawDllMain是静态链接的,所以不必考虑状态切换。
状态信息的作用
在分析了MFC模块状态的实现基础和管理机制之后,现在对状态信息的作用进行专门的讨论。
更多精彩
赞助商链接