如何减小在VS2013下生的exe文件的大小.
2015-09-05 15:18
483 查看
自从 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。
zz:http://blogs.msdn.com/b/vcblog/archive/2012/02/06/10263387.aspx
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 onthem, 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::ExecuteDlgInit, DDX_Control, AfxRegisterMFCCtrlClasses
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:
Moving D2D-related member functions/data out of the _AFX_GLOBAL_DATA class to a separate class
Adding a new virtual method to both CMDIChildWnd and CMDIChildWndEx
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
相关文章推荐
- Hive 1.1.1 启动错误
- Service绑定服务
- deque及迭代器失效问题
- 笔试真题解析 TT 研发工程师笔试卷
- effective c++ 尽量以const enum inline 替换 #define
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- 一个IT人士的个人经历,给迷失方向的朋友
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- iPhone第四节:UIDatePicker、UIPickerView
- 软肋
- VMware Ubuntu下找不到共享文件的解决方法
- 正则表达式
- C++中的虚基类
- 数据结构——堆
- UIWindow ,UIView
- 时尚地图1
- Spring学习之Aop的基本概念
- POJ 3162 Walking Race(树的直径+单调队列)
- HDU 1113 Word Amalgamation -- 字符串处理+排序
- 剑指offer:顺时针打印矩阵