Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1072480
  • 博文数量: 243
  • 博客积分: 3053
  • 博客等级: 中校
  • 技术积分: 2975
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-02 21:11
文章分类

全部博文(243)

文章存档

2013年(2)

2012年(20)

2011年(5)

2010年(114)

2009年(102)

我的朋友

分类:

2010-12-08 18:16:54

2)扩展DLL的模块状态

 7.3.1节指出扩展DLL的实现必须遵循五条规则,为此,首先在扩展DLL实现文件里头,定义AFX_EXTENSION_MODULE类型的静态扩展模块变量,然后在DllMain入口函数里头使用AfxInitExtension初始化扩展模块变量,并且实现和输出一个初始化函数供扩展DLL的使用者调用。

使用者必须具备一个CWinApp对象,通常在它的InitInstance函数中调用扩展DLL提供的初始化函数。

一般用以下的几段代码完成上述任务。首先是扩展模块变量的定义和初始化:

static AFX_EXTENSION_MODULE extensionDLL;

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)

{

if (dwReason == DLL_PROCESS_ATTACH)

{

// Extension DLL one-time initialization

if (!AfxInitExtensionModule(extensionDLL,hInstance))

return 0;

……

}

}

然后是扩展DLL的初始化函数,假定初始化函数命名为InitMyDll,InitMyDll被定义为“C”链接的全局函数,并且被输出。

// wire up this DLL into the resource chain

extern “C” void WINAPI InitMyDll()

{

CDynLinkLibrary* pDLL = new

CDynLinkLibrary(extensionDLL, TRUE);

ASSERT(pDLL != NULL);

...

}

最后是调用者的处理,假定在应用程序对象的InitInstance函数中调用初始化函数:

BOOL CMyApp::InitInstance()

{

InitMyMyDll();

…

}

上述这些代码只有在动态链接到MFC DLL时才有用。下面,对这些代码进行分析和解释

_AFX_EXTENSION_MODULE

在分析代码之前,先讨论描述扩展模块状态的_AFX_EXTENSION_MODULE类。_AFX_EXTENSION_MODULE没有基类,其定义如下:

struct AFX_EXTENSION_MODULE

{

BOOL bInitialized;

HMODULE hModule;

HMODULE hResource;

CRuntimeClass* pFirstSharedClass;

COleObjectFactory* pFirstSharedFactory;

};

其中:

第一个域表示该结构变量是否已经被初始化了;

第二个域用来保存扩展DLL的模块句柄;

第三个域用来保存扩展DLL的资源句柄;

第四个域用来保存扩展DLL要输出的CRuntimeClass类;

第五个域用来保存扩展DLL的OLE Factory。

该结构用来描述一个扩展DLL的模块状态信息,每一个扩展DLL都要定义一个该类型的静态变量,例如extensionDLL。

在DllMain中,调用AfxInitExtensionModule函数来初始化本DLL的静态变量该变量(扩展模块状态),如extensionDLL。函数AfxInitExtensionModule原型如下:

BOOL AFXAPI AfxInitExtensionModule(

AFX_EXTENSION_MODULE& state, HMODULE hModule)

其中:

参数1是DllMain传递给它的扩展DLL的模块状态,如extensionDLL;

参数2是DllMain传递给它的模块句柄。

AfxInitExtensionModule函数主要作以下事情:

(1)把扩展DLL模块的模块句柄hModule、资源句柄hModule分别保存到参数state的成员变量hModule、hResource中;

(2)把当前模块状态的m_classList列表的头保存到state的成员变量pFirstSharedClass中,m_classInit的头设置为模块状态的m_pClassInit。在扩展DLL模块进入DllMain之前,如果该扩展模块构造了静态AFX_CLASSINIT对象,则在初始化时把有关CRuntimeClass信息保存在当前模块状态(注意不是扩展DLL模块,而是应用程序模块)的m_classList列表中。因此,扩展DLL模块初始化的CRuntimeClass信息从模块状态的m_classList中转存到扩展模块状态state的pFirstSharedClass中,模块状态的m_classInit恢复被该DLL改变前的状态。

关于CRuntimeclass信息和AFX_CLASSINIT对象的构造,在3.3.1节曾经讨论过。一个扩展DLL在初始化时,如果需要输出它的CRuntimeClass对象,就可以使用相应的CRuntimeClass对象定义一个静态的AFX_CLASSINIT对象,而不一定要使用IMPLEMENT_SERIAL宏。当然,可以序列化的类必定导致可以输出的CRuntimeClass对象。

(3)若支持OLE的话,把当前模块状态的m_factoryList的头保存到state的成员变量pFirstSharedFactory中。m_factoryList的头设置为模块状态的m_m_pFactoryInit。

(4)这样,经过初始化之后,扩展DLL模块包含了扩展DLL的模块句柄、资源句柄、本模块初始化的CRuntimeClass类等等。

扩展DLL的初始化函数将使用扩展模块状态信息。下面,讨论初始化函数的作用。

 

阅读(1451) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~