在VC11中减小静态链接MFC应用程序的大小

Pat Brenner

null

你好,我是 帕特·布伦纳 是VisualC++图书馆团队的开发人员,我是主要开发人员 Microsoft基础类(MFC) .

在visualstudio2010中,静态链接MFC应用程序的规模大幅增长。我们已经收到了很多关于这个问题的评论,所以我想发表一篇关于原因和解决方案的文章。

原因

在VisualStudio2010中,我们向资源编辑器添加了一个功能,允许您将MFC控件添加到对话框中。MFC控件类型与标准Windows控件一起出现在工具箱中。可以在MFC控件上设置特定于MFC控件的属性,以便它们在创建对话框时按所需的方式运行。

为了让它正常工作 德尔吉尼特 块必须写入项目的RC文件中,其中包含二进制格式的属性信息。这个 德尔吉尼特 在初始化对话框时,必须解析块,因此可以使用中的信息初始化控件 德尔吉尼特 阻止。执行此解析的代码存在于 CWnd::executedginit . 执行的初始化 方法存在于WINCORE.CPP中,它的对象总是包含在每个静态链接的MFC应用程序中(因为它包含 CWnd公司 施工人员和 AfxWndProc公司 方法)。

当然,执行MFC控件初始化的代码需要了解所有MFC控件。反过来,这些控件可能需要了解各种视觉管理器,以便知道如何绘制它们自己。而可视化管理器反过来又依赖于其他MFC类。

这些依赖关系的结果是需要将更多的MFC拉入静态链接的MFC应用程序中,因为链接器无法在构建时确定不需要调用这些方法,因为它们都取决于RC文件的内容和 德尔吉尼特 内部结构。

在visualstudio2010 RTM发布之前不久,我们收到了静态链接MFC应用程序大小增加的警报,但在visualstudio2010发布之前,我们还无法确定原因。即使是这样,我们也很可能无法在发布日期之前完成解决方案的收尾工作,因为我们必须尝试几种不同的方法,然后才能得到一个对MFC开发人员要求很小的工作解决方案。

解决方案

为了解决这个问题,我们消除了MFC类之间的一些依赖关系(更多细节见下文)。我们还移动了几个对MFC控件初始化有影响的方法:

  • CWnd::executedginit , DDXU控制 , AFxRegisterMFCtrlClass类
  • CMFCControlContainer::子类DlgControl CMFCControlContainer::PreUnsubclassControl

分为不同的源模块。

然后以两种不同的方式编译这些独立的源模块:

  • _AFX无MFC控制对话框中的 未定义,它们内置在标准静态MFC库NAFXCW[d].LIB和UAFXCW[d].LIB中,并启用了标准行为。
  • _AFX无MFC控制对话框中的 #定义后,它们被内置到一个新的小型静态MFC库AFXNMCD[d].LIB中, 没有 在对话框上初始化MFC控件的能力(库名称中的NMCD是“的缩写” 对话框上没有MFC控件 ”.)

新的较小的库与较大的标准MFC库具有相同的方法(相同的名称,但不同的实现),因此我们必须确保首先链接它。这样可以确保使用对MFC控件初始化没有任何依赖关系的函数,并且消除依赖关系。这是通过在新的源模块中定义的符号和通过 #布拉格马 AFX.H中的语句基于 #定义 一切就绪。

这项工作的结果是你可以 #在对话框中定义u AFX u NO u MFC u控件 在MFC应用程序的 标准尺寸X.h 所有在对话框上执行MFC控件初始化的代码都将从应用程序中删除。在一个简单的基于对话框的应用程序中,这将使应用程序的大小减少大约80%[注意如果你 在对话框上使用MFC控件,并使用 _AFX无MFC控制对话框中的 #定义后,应用程序可能根本无法运行(或不会出现对话框),因为无法创建包含不存在的窗口类的对话框。我们补充道 痕迹 向货币金融委员会作出的这方面的声明,以帮助指出这一问题。]

此外,我们还对MFC应用程序向导生成的代码进行了更改。它将生成包含 #ifdef公司 代表 _AFX无MFC控制对话框中的 ,所以:

  • 对话框将从 C对话 而不是 CDialogEx公司 如果 #定义 已设置。
  • CShell管理器 将在应用程序的 初始化实例 方法如果 #定义 已设置。

我们已经在MFC中为visualstudio的下一个主要版本实现了这些更改。现在我们已经了解了原因和最佳解决方案,我们研究了将这些更改移植回VisualStudio2010的可能性,以便使使用该版本构建的应用程序受益。不幸的是,我们为减少MFC类之间的依赖关系所做的更改包括:

  1. 将D2D相关成员函数/数据移出 _AFX全球数据 一个单独的班级
  2. 将新的虚拟方法添加到 CMDIChildWnd公司 CMDIChildWndEx公司
  3. 将新方法添加到 CWinApp公司

因为这些更改引入了二进制不兼容,所以如果不中断现有的MFC应用程序,我们就无法将这些更改移植回visualstudio2010。

我希望你觉得这些信息有用!

帕特·布伦纳 Visual C++开发

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享