文 / 李博(光宇广贞)
实验平台 VS 2010,具体信息见:《测试 VS 2010 对 C++ 0x 标准的谨慎支持》。
CRT 库是裹在 OS API 上的,所以用 C / CPP 写的程序能够运行。我们可以扔掉 CRT 库直接调用 OS API 完成动作,以此缩减文件尺寸。
首先指定程序入口。控制台程序默认入口是 main;Win 窗体程序默认是 WinMain;Dll 默认是 DllMain。其实程序在链接 CRT 库时,三者对应如下:
函数名 |
默认值 |
mainCRTStartup(或 wmainCRTStartup) | 使用 /SUBSYSTEM:CONSOLE 的应用程序;调用 main(或 wmain) |
WinMainCRTStartup(或 wWinMainCRTStartup) | 使用 /SUBSYSTEM:WINDOWS 的应用程序;调用 WinMain(或 wWinMain),它须用 __stdcall 定义 |
_DllMainCRTStartup | Dll;调用 DllMain(若存在),DllMain 须用 __stdcall 定义 |
注意控制台程序 main / wmain 必须是 __cdecl 约定,因此需要指定为其它函数,比如写成 Main 丫就不认识了,就不会认为是 main / wmain 从而强制调用约定。
链接(Linker)参数 /ENTRY 指定为自己的函数,比如此例为 Main。同时,默认的函数调用约定改为 __stdcall。
链接参数指定 /NODEFAULTLIB,扔掉一切 CRT 库。指定后,编译参数是否指定 /Zl 都一样。
编译选项指定 /MT,使用静态库解析外部符号。
事儿还没完,若使用到标准输入输出终端,还要指定编译参数 /GS-,不做缓存检查。
如下示例:
使用上述方法正确执行。扔掉了 CRT 库,便可以不受 CRT 库版本的限制,只要是 Win 系统就可以运行,唯一的问题只是运行基于的系统是否支持 WriteConsole 等函数了。