如何减小 Visual C++ 2010 静态编译出的 MFC 可执行文件的大小

最近发现一篇好文,国内基本搜索不到相关内容,于是将其翻译出来。基本上是看完了全文之后,通过自己的理解意译出来的,原文地址(需要 翻,墙。):http://tedwvc.wordpress.com/2010/05/27/how-to-make-small-statically-linked-mfc-exes-in-visual-c-2010/

在上一篇博文中,我用了一个简单的办法来比较 2010 与 2008 生成的静态编译的文件大小。如果创建一个简单的 MFC SDI 程序--只带有经典的菜单、外观以及工具栏--仅仅 600K 而不是 1800K 的大小。

其实,经典 MFC 源代码中只有 3 个文件与特性包有关,就是它们使得接连时大小增大。如果我们在自己的工程中将这 3 个源代码文件修改,去除对特性包代码的引用,就会让生成的 exe 文件大小急剧下降到 600K。

当然,我们要确保没有使用到任何特性包带有的类库,因为只要引用了一个库,其它与之依赖的大部分库都会被链接进来。这里我特别要提一下 CDialogEx。CDialogEx 是在 MFC 向导中新增加的对话框基类,包括“关于”对话框也继承了它。其实 CDialogEx 相对来说没有什么用,除非你想要改变对话框的背景颜色、图片,我也不推荐这么做。所以,首先要把你的工程中所有继承 CDialogEx 的地方都改成 CDialog(所以基类及方法等)。你可以使用查找和替换来达到这个目的。

然后,根据以下步骤将你的可执行文件的大小缩小到原来的水平。

1)创建一个默认的不包含任何新特性的 MFC SDI 程序(MFC 标准,原生、默认的外观,经典菜单,经典可停靠工具条,没有重新启动管理器)(如果你已经有原有的工程,可以跳过这一步)。
2)在配置属性中设置为静态链接 MFC 库。
3)将下面 3 个源代码文件复制到你的工程中(从 Visual Studio 2010 的安装目录里面的 MFC 源代码文件目录复制到你自己的源代码目录中,一般会在某个盘的 program files\microsoft visual studio 10.0\vc\atlmfc\src\mfc 里面,然后用“添加 -- 现有项”加入工程中。)

afxctrlcontainer.cpp
afxglobals.cpp
winmdi.cpp

4)根据下面所述(或者使用 #if 0/#endif ),注释掉上一步 3 个文件中的部分代码:

在 afxctrlcontainer.cpp 文件中:
注释掉 afxctrlcontainer.h 这一行之后的所有引用(所有 #include 行)
注释掉 CMFCControlContainer::CreateDlgControl 中的所有代码
注释掉 PreUnsubclassControl 中的所有代码
注释掉 ReadBoolProp 中对 tagManager 的调用

在 afxglobals.cpp 文件中:
注释掉 comdef.h 这一行之后除了 afxglobals.h 之外的所有引用
注释掉 “Notify toolbars about font changing:”开关的那一段代码
注释掉对 CPaneFrameWnd 的调用
注释掉对 AfxIsExtendedFrameClass 的调用
注释掉对 AfxIsMFCToolbar 中的 CMFCToolbar 的调用

在 winmdi.cpp 文件中:
注释掉 sfdafx.h 之后的两个引用
注释掉 UpdateClientEdge 里面 CMDIChildWndEx 开头的代码段

5)在你的工程中的 stdafx.h 文件中加入下面几行(这是 MFC 内部所需的一些文件,你也可以把它们加到独立的源代码文件中):

#include "afxpriv.h"
#include "afxole.h"
#include "..\src\mfc\oleimpl2.h"
#include "..\src\mfc\afximpl.h"

6)删除下面内容

在 stdafx.h 文件中里面删除 #include <afxcontrolbars.h>

删除整个项目中对 CShellManager 的所有调用。

编译时还会提示一些错误,根据提示注释(删除)掉那些零散的代码。

完成上面这个步骤之后,重新编译你的发行版,你会发现生成的 exe 大小已经缩小了(上面提到的 exe 文件会从 1800K 变到 600K)。


已经修改好的文件稍后传到 CSDN 资源中。


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CMake是一个跨平台的构建系统。它可以自动生成Makefile或是Visual Studio的项目文件,以达到构建目标的效果。 静态编译指所有用到的第三方库都会被链接到最终的二进制文件中,因此这种方式生成的可执行文件可以在不同的机器上运行,而不必考虑库文件的路径和版本等问题。 下面是一个简单的CMakeLists.txt文件,用于生成一个静态编译的可执行文件。 ```cmake cmake_minimum_required(VERSION 3.5) project(demo) set(CMAKE_CXX_COMPILER "g++") set(CMAKE_CXX_STANDARD 11) set(SOURCES main.cpp) set(LIBRARIES lib1 lib2) include_directories(include) add_executable(demo ${SOURCES}) target_link_libraries(demo ${LIBRARIES}) ``` 在这个例子中,我们定义了一个项目名称为demo,设置了编译器为g++,使用C++11标准进行编译。我们还定义了源码文件名为main.cpp,库文件名为lib1和lib2。在CMakeLists.txt中,我们通过add_executable命令将源码文件编译成可执行文件,并通过target_link_libraries命令将库文件链接到可执行文件中。 在项目目录下执行以下指令: ```bash mkdir build && cd build cmake .. make ``` 即可在build目录下生成可执行文件demo。我们可以使用ldd命令查看可执行文件的依赖关系,发现所有依赖库都已经被链接到了二进制文件中。 ```bash ldd demo ``` 需要注意的是,静态编译的可执行文件可能会比较大,因为它包含了所有的依赖库,因此需要权衡可执行文件大小和可移植性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值