软件频道>程序开发>JavaVBVCDelphiC/C++Web开发微软专栏移动数据库程序人生软件工程|开发客
您现在的位置: 天极网 > 开发频道 > VC++动态链接库编程之MFC扩展 DLL
全文

VC++动态链接库编程之MFC扩展 DLL

2005-10-10 08:52作者:宋宝华出处:天极网责任编辑:方舟
天极软件专题专区精选     到天极软件“读编交流区”畅所欲言
Google专区 POPO专区 QQ专区 QQ挂机 了解Web2.0
Flash MX 视频教程 Photoshop视频教程 网页设计视频教程 照片处理数字暗房
PPT动画演示教程 Excel动画教程集 Word动画演示教程 Windows Vista专区
特洛伊木马专区 黑客知识教程专区 防火墙应用专区 注册表应用专区
Windows API开发专区 网络编程专区 VB数据库编程专区 图像处理与多媒体编程

  前文我们对非MFC DLL和MFC规则DLL进行了介绍,现在开始详细分析DLL的最后一种类型――MFC扩展DLL。

  6.1概论

  MFC扩展DLL与MFC规则DLL的相同点在于在两种DLL的内部都可以使用MFC类库,其不同点在于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类型 入口函数
非 MFC DLL 编程者提供DllMain函数
MFC规则 DLL CWinApp对象的InitInstance 和 ExitInstance
MFC扩展 DLL MFC DLL向导生成DllMain 函数

  对于MFC扩展DLL,系统会自动在工程中添加如下表所示的宏,这些宏为DLL和应用程序的编写提供了方便。像AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA这样的宏,在DLL和应用程序中将具有不同的定义,这取决于_AFXEXT宏是否被定义。这使得在DLL和应用程序中,使用统一的一个宏就可以表示出输出和输入的不同意思。在DLL中,表示输出(因为_AFXEXT被定义,通常是在编译器的标识参数中指定/D_AFXEXT);在应用程序中,则表示输入(_AFXEXT没有定义)。

定义
AFX_CLASS_IMPORT __declspec(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 _AFXEXT
 AFX_CLASS_EXPORT
#else
 AFX_CLASS_IMPORT
AFX_EXT_API #ifdef _AFXEXT
 AFX_API_EXPORT
#else
 AFX_API_IMPORT
AFX_EXT_DATA #ifdef _AFXEXT
 AFX_DATA_EXPORT
#else
 AFX_DATA_IMPORT

  6.2 MFC扩展DLL导出MFC派生类

  在这个例子中,我们将产生一个名为“ExtDll”的MFC扩展DLL工程,在这个DLL中导出一个对话框类,这个对话框类派生自MFC类CDialog。

  使用MFC向导生成MFC扩展DLL时,系统会自动添加如下代码:

static AFX_EXTENSION_MODULE ExtDllDLL = { NULL, NULL };
extern "C" int APIENTRY

DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
 // Remove this if you use lpReserved

 UNREFERENCED_PARAMETER( lpReserved );

 //说明:lpReserved是一个被系统所保留的参数,对于隐式链接是一个非零值,对于显式链接值是零

 if (dwReason == DLL_PROCESS_ATTACH)
 {
  TRACE0( "EXTDLL.DLL Initializing!\n" );
  // Extension DLL one-time initialization
  if ( !AfxInitExtensionModule( ExtDllDLL, hInstance ))
   return 0;
   // Insert this DLL into the resource chain
  new CDynLinkLibrary( ExtDllDLL );
 }
 else if (dwReason == DLL_PROCESS_DETACH)
 {
  TRACE0( "EXTDLL.DLL Terminating!\n" );
  // Terminate the library before destructors are called
  AfxTermExtensionModule( ExtDllDLL );
 }
 return 1; // ok
}

  这一段代码含义晦涩,我们需要对其进行解读:

  (1)上述代码完成MFC扩展DLL的初始化和终止处理;

  (2)初始化期间所创建的 CDynLinkLibrary 对象使MFC扩展 DLL 可以将 DLL中的CRuntimeClass 对象或资源导出到应用程序;

  (3)AfxInitExtensionModule函数捕获模块的CRuntimeClass 结构和在创建 CDynLinkLibrary 对象时使用的对象工厂(COleObjectFactory 对象);

  (4)AfxTermExtensionModule函数使 MFC 得以在每个进程与扩展 DLL 分离时(进程退出或使用AfxFreeLibrary卸载DLL时)清除扩展 DLL;

  (5)第一条语句static AFX_EXTENSION_MODULE ExtDllDLL = { NULL, NULL };定义了一个AFX_EXTENSION_MODULE类的静态全局对象,AFX_EXTENSION_MODULE的定义如下:

struct AFX_EXTENSION_MODULE
{
 BOOL bInitialized;
 HMODULE hModule;
 HMODULE hResource;
 CRuntimeClass* pFirstSharedClass;
 COleObjectFactory* pFirstSharedFactory;
};

  由AFX_EXTENSION_MODULE的定义我们可以更好的理解(2)、(3)、(4)点。

  在资源编辑器中添加一个如图15所示的对话框,并使用MFC类向导为其添加一个对应的类CExtDialog,系统自动添加了ExtDialog.h和ExtDialog.cpp两个头文件。


图15 MFC扩展DLL中的对话框

  修改ExtDialog.h中CExtDialog类的声明为:

class AFX_EXT_CLASS CExtDialog : public CDialog
{
 public:
  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_CLASS”宏,则使得DLL中的CExtDialog类被导出。

软件资讯·软件下载尽在天极软件

共3页。 1 2 3 下一页 末页
相关搜索:
相关文章及软件
关注此文读者还看过
文章排行
本周
本月
最近更新
关于我们|About us|网站律师|天极服务|电子杂志|RSS订阅|加入我们|网站地图
TMG
Copyright (C) 1999-2009 Chinabyte.com, All Rights Reserved 版权所有 天极网络
商务联系、网站内容、合作建议:010-82657868
版权声明 在线提交意见反馈 渝ICP证B2-20030003号
经营性网站备案信息 网警备案 中国网站排名
天极传媒:天极网|比特网|IT专家网|IT商网|52PK游戏网|IT分众