静态链接到MFC的DLL

2MFC DLL

       MFC DLL中使用对话框不像Win32 DLL中那么简单,主要是因为MFC程序中存在一个模块状态(Module State)的问题,也就是资源重复的问题。(此处的术语模块是指一个可执行程序,或指其操作不依赖于应用程序的其余部分但使用MFC运行库的共享副本的一个DLL(或一组DLL)。我们所创建的MFC DLL就是这种模块的一个典型实例。)

 

       在每个模块(EXEDLL)中,都存在一种全局的状态数据,MFC依靠这种全局的状态数据来区分不同的模块,以执行正确的操作。这种数据包括:Windows实例句柄(用于加载资源),指向应用程序当前的CWinAppCWinThread对象的指针,OLE模块引用计数,以及维护Windows对象句柄与相应的MFC对象实例之间连接的各种映射等。但当应用程序使用多个模块时,每个模块的状态数据不是应用程序范围的。相反,每个模块具有自已的MFC状态数据的私有副本。这种全局的状态数据就叫做MFC模块状态。

 

模块的状态数据包含在结构中,并且总是可以通过指向该结构的指针使用。当代码在执行时进入了某一个模块时,只有此模块的状态为“当前”或“有效”状态时,MFC才能正确的区分此模块并执行正确的操作。

 

例如,MFC应用程序可以使用下面代码从资源文件中加载字符串:

 

CString str;

str.LoadString(IDS_MYSTRING);

 

使用这种代码非常方便,但它掩盖了这样一个事实:即此程序中IDS_MYSTRING可能不是唯一的标识符。一个程序可以加载多个DLL,某些DLL可能也用IDS_MYSTRING标识符定义了一个资源。MFC怎样知道应该加载哪个资源呢?MFC使用当前模块状态查找资源句柄。如果当前模块不是我们要使用的正确模块,那么就会产生不正确的调用或者错误。

 

按照MFC库的链接方法,一个MFC DLL有两种使用MFC库的方法:静态链接到MFCDLL和动态链接到MFCDLL。下面我们就按照这两种类型的MFC DLL来介绍如何切换当前模块状态以正确的在MFC DLL中使用资源。

1、静态链接到MFCDLL

静态链接到MFC的规则DLLMFC库静态链接,则此时MFC库不能共享,所以MFC总是使用它所链接的DLL的模块状态。这样也就不存在管理模块状态的问题。但使用这种方法的缺点是DLL程序将会变大,而且会在程序中留下重复代码。下面给出的例子验证了这一点。本例可以按照以下步骤来完成:

 

1)在VC菜单中File->New新建一个命名为DLLStaticMFC AppWizard的工程,下一步选择Regular DLL with MFC statically linked

 

2)在工程中添加一个对话框资源,其ID为:IDD_ABOUTBOX。并在resource.h之中将IDD_ABOUTBOX 的数值改为100

 

3)在DLLStatic.cpp中定义如下函数:

 

void ShowDlg()

{

       CDialog dlg(IDD_ABOUTBOX);

       dlg.DoModal();

}

 

4)在DLLStatic.def文件中的EXPORTS语句中添加一行:ShowDlg,以导出ShowDlg函数。

 

5)编译生成DLLStatic.dllDLLStatic.lib

 

继续使用上一节中的Use工程,将前面生成的DLLStatic.dllDLLStatic.lib两个文件复制到工程的Debug目录内,并将

 

extern "C" __declspec(dllexport) void ShowDlg();

#pragma comment(lib,"debug/UseDlg")

 

这两行改为:

 

void ShowDlg();

#pragma comment(lib,"debug/DLLStatic")

 

编译并运行Use.exe。点击按钮,可以看到DLLStatic中的模态对话框弹出。

 

本例中,可以注意到DLL中所定义的About对话框资源与EXE中所定义的About对话框资源ID完全相同,但是当我们点击Use.exe上面的按钮时,弹出的是DLL中的模态对话框。说明,当使用静态链接到MFC的规则DLL时,不存在管理模块状态的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值