VC2008中影响exe大小和速度的编译选项

发布时间:2014年4月15日 作者:未知 查看次数:1281

VC2008中影响exe大小和速度的编译选项


转:http://blog.sina.com.cn/s/blog_648d306d0100ryvv.html

以IDE的工程设置里面的排列顺序介绍,某些选项需要自己手动添加的最后介绍,后面说的默认值是release的,debug版本一般不需要调选项。

项目 - 属性 - 配置属性 - C/C++,这是编译器选项。

优化:
  通常,算法程序选择最大化速度(/O2),界面程序选择最小化大小(/O1),可以获得最佳的效果。
优选大小或速度,只有在使用完全优化(/Ox)时才有效,完全优化一般不推荐使用,用处就是可以生成速度与/O2基本相当,但是体积更小的代码(选速度优先的话)。

  其他几个选项实际上已包含在/O1、/O2之中,具体请看MSDN。

代码生成:
  启用字符串池(/GF),会将相同的字符串合并,当然可以减小空间占用,虽然本项目默认没有打开,但是默认的/Zi选项会自动打开/GF,这里打不打开一样。
  启用C++异常:该项默认打开,在C++项目中(比如MFC中),会大大增加程序体积,增加约30%,关闭并不代表try不能用了,但会一定程度上降低健壮性,对于空间要求较高的程序,建议关闭。对于正式项目,请参见MSDN,看看会不会造成不利影响。
  运行库:默认多线程DLL(/MD),体积最优的方案,如果对方没有VS运行时库,选择/MT会将C/C++运行库静态编译,体积增加不少,因此,我的选择一般是程序与redist包一起发布,也就几M,而且以后永远可以接受/MD版本了。
  缓冲区安全检查:关闭的话,减少0.5K~1K体积(默认情况,VC的段长度512字节,因此程序体积变化的最小单位是0.5K)。
  启用增强指令集:真想用SSE3的话去用Intel C++,VS2008只支持到SSE2,而且,在我的机器上貌似使用默认设置就能达到选择SSE2的相同速度,如果安装了Intel C++ 11,可集成与VS2008,同样的地方选择SSE3效果超群
  浮点模型:精确还是快速理论上肯定对速度有影响,但是我极少使用浮点编程,我的方向是系统、安全和密码,都是整数的天下。

高级:
  编译为C还是C++影响不大,这充分说明了C++简单面向对象特性和C效率差不多(如重载,默认情况下,编译器会检查扩展名决定目标代码类型,对于cpp文件,所有的函数都会编译为可重载的类型,但是对效率几乎没有影响)。

项目 - 属性 - 配置属性 - 链接器,这是链接器选项。

输入:
  忽略库只有在库冲突时候才有用,VC绝对不会连接没有调用到的库,哪怕你明确指定了。

清单文件:
  完全使用API编程可以不生成清单。减少约1K体积。
  一般情况下,关闭UAC的那一项,可减少0.5K。

调试:
  关闭“生成调试信息(/DEBUG)”,根据程序规模,可减少1K~几十K。

优化:
  release模式,默认情况下已经该组已经最优了,/OPT:REF和/OPT:ICF已经打开,注意,VS2005、VS2008中Windows 98优化那一项没用,不像VC6取消Windows 98优化可以大大减小体积。因为VS2005、VS2008中段大小已经是512字节,VC6默认4K。

高级:
  指定入口点,可以大大减小程序体积,但是不调用CRT的入口无法自动处理参数,可用GetCommandLine和CommandLineToArgvW这两个API来处理参数。
  随机基址:默认模式启用映像随机化(/DYNAMICBASE),会大大增加程序体积,因为这是个增加程序防反编译、防破解能力的选项。如无需求,请选择禁用映像随机化(/DYNAMICBASE:NO),文件越大,体积缩小越明显,至少30%

命令行:
  小程序,可以指定段大小/ALIGN,/O1编译的化最小可以使用/ALIGN:4,这个选项不推荐,第一有点规模的程序就不能用太小的段,/O2优化的也不能用小段,而且默认的512字节段可以使用UPX压缩,再小就不能了,除非咱们编译那种600字节的Hello World,这个选项意义不大,因此微软才没有给他一个图形选项。
  同样,编译600字节hello world还需要/merge合并段选项,同样不推荐使用。

  有些选项VS2005和VS2003没有,VS2003还包括几个VS2008废除的选项,实际上VC里面程序优化效率最高的个人感觉是VS2003。 VC6的界面差别比较大,选项有一定差异,但毕竟都是微软的产品,差别不大,甚至于MASM这个汇编编译器,连接选项大都与VC相同……

    再说一点,VS2008SP1的MFC工程会自动生成巨大的256*256真彩图标,因此默认的MFC对话框程序都有近100K,建议删除多余的图标,配合上述选项能减到10多K。

以上转自网络
--------------------------------------

在指定入口点后,不调用CRT的入口无法自动处理参数,要自行处理。

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
 UNREFERENCED_PARAMETER(hPrevInstance);
 UNREFERENCED_PARAMETER(lpCmdLine);

  // TODO: 在此放置代码。
 MSG msg;
 HACCEL hAccelTable;

 hInstance=GetModuleHandle(NULL);
 // 初始化全局字符串
 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
 LoadString(hInstance, IDC_TNEW, szWindowClass, MAX_LOADSTRING);
 MyRegisterClass(hInstance);

 nCmdShow=SW_SHOW;
 // 执行应用程序初始化:
 if (!InitInstance (hInstance, nCmdShow))
 {
  return FALSE;
 }

 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TNEW));

 // 主消息循环:
 while (GetMessage(&msg, NULL, 0, 0))
 {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }
 ExitProcess(0);  //退出,return不行
 return (int) msg.wParam;
}

-----------------------------

WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)参数

转:

hInstance:应用程序当前实例的句柄。 
hPrevlnstance:应用程序的先前实例的句柄。对于同一个程序打开两次,出现两个窗口第一次打开的窗口就是先前实例的窗口。对于一个32位程序,该参数总为NULL。 如果需要检测另外一个实例是否已经存在,则使用CreateMutex函数创建一个独一无二的名字。即使互斥名已经存在,CreateMutex函数也是成功的,但是GetLastError函数将返回 ERROR_ALREADY_EXISTS,这就表明应用程序有另外一个实例存在,因为它首先创建了互斥名。
lpCmdLine:指向应用程序命令行的字符串的指针,不包括执行文件名。获得整个命令行,参看GetCommandLine。 第三个参数lpCmdLine是一个以空终止的字符串,指定传递给应用程序的命令行参数。例如:在D盘下有一个sunxin.txt文件,当我们用鼠标双击这个文件时将启动记事本程序(notepad.exe),此时系统会将D:\sunxin.txt作为命令行参数传递给记事本程序的WinMain函数,记事本程序在得到这个文件的全路径名后,就在窗口中显示该文件的内容。要在VC++开发环境中向应用程序传递参数,可以单击菜单【Project】→【Settings】,选择“Debug”选项卡,在“Program arguments”编辑框中输入你想传递给应用程序的参数。
nCmdShow:指明窗口如何显示。该参数可以是下列值之一: SW_HIDE:隐藏窗口并且激活另外一个窗口。 SW_MINIMIZE:最小化指定的窗口,并且激活在系统表中的顶层窗口。 SW_RESTORE:激活并显示窗口。如果窗口已经最小化或最大化,系统将以恢复到原来的尺寸和位置显示窗口(与SW_SHOWNORMAL相同)。 SW_SHOW:激活一个窗口并以原来的尺寸和位置显示窗口。 SW_SHOWMAXIMIZED:激活窗口并且将其最大化。 SW_SHOWMINIMIZED:激活窗口并将其目标化。 SW_SHOWMINNOACTIVE:将一个窗口显示为图标。激活窗口维持活动状态。 SW_SHOWNA:以窗口的当前状态显示窗口。激活窗口保持活动状态。 SW_SHOWNOACTIVATE:以窗口的最近一次的尺寸和位置显示窗口。激活窗口维持激活状态。 SW_SHOWNORMAL:激活并显示窗口。如果窗口最大化或最小化,系统将其恢复到原来的尺寸和位置(与SW_RESTORE相同)。

 



版权所有!www.sieye.cn
E.Mail:sieye@sohu.com QQ:66697110