WEB开发网
开发学院软件开发VC 使用LIBCTINY.LIB为EXE和DLL文件减肥 阅读

使用LIBCTINY.LIB为EXE和DLL文件减肥

 2010-07-15 20:45:18 来源:WEB开发网   
核心提示:在 October 1996 column 我讨论过一个有关可执行文件大小的问题,那个时候,使用LIBCTINY.LIB为EXE和DLL文件减肥,一个简单的 hello world 程序大约有32KB,在 Visual C++® 编译器更新了两个版本后,我都会延迟加载,我在过去的专栏里面讨论过延迟加载,文件尺寸

在 October 1996 column 我讨论过一个有关可执行文件大小的问题。那个时候,一个简单的 hello world 程序大约有32KB。在 Visual C++® 编译器更新了两个版本后,文件尺寸问题稍微得到了改善,同样的程序使用 Visual C++® 6.0 编译器现在只有28KB。在那时的专栏里,我使用了一个小的运行库来创建极小的可执行程序。虽然有不少局限,但是对决大多数的程序来说,它们运转得很好。这些局限已经存在相当长的一段时间了,我决心修正它们。同时也提供一个学习如何进一步减少程序的尺寸的鲜为人知的知识。

DLL 和 EXE 的尺寸

在替换运行库之前,我们得先花点时间看看为什么EXE和DLL的大小比你想象的要大。考虑下面标准的 Hello World 程序:#include <stdio.h>
void main()
{
  printf ("Hello World!
" );
}
使用下列命令编译并产生一个map文件(译者著:如果 CL 不能正确执行,在控制台下先执行VC98BinVCVARS32.BAT)Cl /O1 Hello.CPP /link /MAP

首先,查看 .MAP 文件(Figure1展示了一个裁减过的版本),从 main (0001:00000000) 和 printf (0001:0000000C) 的地址来看,可以推断主函数只有 oxC 字节的长度。再看这个文件的最后一行 __chkstk( 0001:00003B10),可以估计可执行代码至少有 0x3B10 字节,其中将近14KB的代码将 Hello World 送到屏幕。

现在,再看看.MAP 文件中的其它行。有些项是有用的,比如,__initstdio 函数支持 printf 将输出写到文件,所以这类支持 stdio 的库函数是有意义的。再如 strlen,它会被printf调用,所以它包含在 .MAP 中就不足为奇了。

不过,我们再看看其它函数,比如 __sbh_heap_init。它是运行库的堆初始化程序, 而Win32的操作系统也提供了一些类似 HeapAlloc 的函数来实现堆分配。虽然C++运行库选择Win32的堆函数可能带来性能上的提高,但是 Visual C++ 并没有这样做。所以最后在可执行文件上增加了许多不必要的代码。

有些人并不介意运行库实现自己的堆,但这里有更缺乏说服力的例子。看看 map 文件底部的 __crtMessageBoxA 函数,这个函数使得可执行文件可以通过运行库而非 USER32.dll 来调用 MessageBox API。但对于一个简单的hello world 程序来说,是否要调用 MessageBox 是很难预见的。

再看一个例子:函数 __crtLCMapStringA 将字符串转做区域转换。区域支持是微软的责任,但是对大多数程序并不需要。所以就没有必要为区域转换花费开销。

我还可以继续列举那些不必要的东西,不过我已经证明了自己的观点:一个典型的小程序包含了很多不会被使用的代码,对于各个代码片段而言,并没有增加了多少代码的尺寸,但是将它们全部加起来将是相当可观的。

关于C++动态连接的运行库

留心的读者可能会说,“Matt! 为什么不使用C++动态链接的运行库?”。在过去我不会这样用,因为在 Windows 95, Windows 98, Windows NT 3.51, Windows NT 4.0 这几个平台中C++动态链接的运行库命名不统一。不过幸运的是,现在情况改变了,大多数情况下你绝对可以信赖你机器上的 MSVCRT.DLL。

重新编译你的MSVCRT (译者注:cl /O1 /MD Hood.c /link /map), 很不错,可执行文件只有16KB。重要的是你把一些不需要的代码移到了 MSVCRT.DLL。只不过在程序启动的时候你要多引导一个DLL。此DLL还包含了类似区域转换的支持。如果MSVCRT能够满足你的需要,那么就尽量使用它。只不过,我还是相信使用一个裁减的,静态运行库是个不错的东西。

我不知道我该不该这样做,不过通过和读者的邮件交流,我坚信我并不孤独,许多朋友都跟我一样希望代码尽可能的小。现代一般用的可写光盘和快速的网络连接,是不需要担心代码尺寸。但是我在家中最快的网络连接也只有24Kbps.我讨厌浪费时间去下载一个臃肿的页面。

作为我的一个原则,我希望代码尽可能的小。我不愿意装载任何我不需要的DLLs。甚至我可能要用到一个DLLs,我都会延迟加载。我在过去的专栏里面讨论过延迟加载,如果你想熟悉它。可以先看看 Under the Hood in the December 1998 issue of MSJ for starters

1 2 3  下一页

Tags:使用 LIBCTINY LIB

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接