如何减小在VS2013下生的exe文件的大小.

自从 VS2005 升级到 VS2010 之后,build出来的文件(exe、dll)就莫名的增大了很多,MSDN的blog上有一篇blog,详细描述了size增大的原因,以及缩减的方法。

总结如下
原因:
size增大是因为 DLGINIT  的引入。他允许在dialog上增加MFC控件。而这个function在static link的过程中会引入很多可能并不需要的function,因为在build的过程中无法预知是否需要这些function。

解决方法:
1,
在"stdafx.h"中增加如下 宏定义
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
.这行放到stdafx 的最上面 (#pragma once 下面)
2,
CDialog的父类需要有 CDialogEx 修改为 CDialog
3,
InitInstance中禁止创建CShellManager,也就是需要将
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

注释掉。


通过宏定义的方法,来link不同的 lib ,不同的lib的差别在于dialog上是否支持MFC control。这样的代价是在Dialog上无法使用MFC control。




Reducing the Size of Statically-linked MFC Applications in VC11

Hello, I’m Pat Brenner, a developer on the Visual C++ Libraries team, and I am the primary developer working on the Microsoft Foundation Classes (MFC).

In Visual Studio 2010, the size of statically-linked MFC applications grew substantially. We’ve gotten a number of comments about this issue, so I wanted to post an article about the cause and the solution that we have come up with.

Cause

In Visual Studio 2010, we added a feature to the resource editor which allows you to add MFC controls to your dialogs. The MFC control types appear in the toolbox along with the standard Windows controls. Properties specific to the MFC controls can be set on them, so they behave as desired when the dialog is created.

In order for this to work properly, a DLGINIT block has to be written in the RC file for the project, which contains the properties information in binary format. The DLGINIT block has to be parsed when the dialog is being initialized, so the controls can be initialized using the information in the DLGINIT block. The code to do this parsing lives in CWnd::ExecuteDlgInit.ExecuteDlgInit method lives in WINCORE.CPP, whose object is always included in every statically-linked MFC application (because it contains the CWnd constructors and the AfxWndProc method).

The code that performs the MFC control initialization, of course, needs to know about all of the MFC controls. Those controls, in turn, may need to know about various visual managers in order to know how to draw themselves. And the visual managers, in turn, have dependencies on other MFC classes.

The result of these dependencies is that much more of MFC needs to be pulled into a statically-linked MFC application, because the linker cannot determine at build time that none of those methods will need to be called, since it all depends on the content of the RC file and DLGINIT structures inside it.

We were alerted to this size increase in statically-linked MFC applications shortly before the release of Visual Studio 2010 RTM, but we were not able to definitively establish the cause before Visual Studio 2010 shipped. Even if we had, we most likely would not have been able to put the finishing touches on a solution before the release date, because we had to try several different approaches before arriving at a working solution that puts a very small requirement on the MFC developer.

Solution

To fix the problem, we eliminated a number of dependencies between MFC classes (further details are below). We also moved several methods that have an effect on the MFC control initialization:

  • CWnd::ExecuteDlgInitDDX_ControlAfxRegisterMFCCtrlClasses
  • CMFCControlContainer::SubclassDlgControls andCMFCControlContainer::PreUnsubclassControl

into separate source modules.

These separate source modules are then compiled in two different ways:

  • With _AFX_NO_MFC_CONTROLS_IN_DIALOGS not #defined, they are built into the standard static MFC libraries, NAFXCW[d].LIB and UAFXCW[d].LIB, with the standard behavior enabled.
  • With _AFX_NO_MFC_CONTROLS_IN_DIALOGS #defined, they are built into a new small static MFC library, AFXNMCD[d].LIB, without the ability to initialize MFC controls on dialogs. (The NMCD in the library name is an acronym for “No MFC Controls on Dialogs”.)

The new smaller library has the same methods (same names, but different implementations) as the larger standard MFC libraries, so we must make sure to link it in first. This ensures that the functions that don’t have any dependency on MFC control initialization are used and the dependencies are eliminated. This is accomplished via symbols that are defined in the new source modules, and force-included via #pragma statements in AFX.H based on #defines set.

The result of this work is that you can simply #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS in your MFC application’sstdafx.h file, and all the code that performs MFC control initialization on dialogs will be left out of your application. In a simple dialog-based application, this will reduce the size of the application by approximately 80%. [Note that if you do use MFC controls on a dialog, and build with _AFX_NO_MFC_CONTROLS_IN_DIALOGS #defined, your application may not run at all (or dialogs will not appear) because a dialog containing a nonexistent window class cannot be created. We added TRACE statements to MFC to this effect to help point out this issue.]

In addition, we have made changes in the code generated by the MFC application wizard. It will generate code that contains#ifdefs for the _AFX_NO_MFC_CONTROLS_IN_DIALOGS, so:

  • Dialogs will be derived from CDialog instead of CDialogEx if the #define is set.
  • No CShellManager will be created in the application’s InitInstance method if the #define is set.

We have implemented these changes in MFC for the next major release of Visual Studio. Now that we understand the cause and the best solution, we looked at the possibility of porting the changes back to Visual Studio 2010 in order to benefit applications built with that version. Unfortunately, the changes we made to reduce the dependencies between MFC classes included:

  1. Moving D2D-related member functions/data out of the _AFX_GLOBAL_DATA class to a separate class
  2. Adding a new virtual method to both CMDIChildWnd and CMDIChildWndEx
  3. Adding a new method to the CWinApp class

Because these changes introduce binary incompatibilities, we are not able to port the changes back to Visual Studio 2010 without breaking existing MFC applications.

I hope you find this information helpful!

 

 

Pat Brenner 
Visual C++ Libraries Development


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值