51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

如何减小EXE、DLL文件的大小

普通Exe 文件 {#普通Exe-文件}

完全可以使用下面方法:

A. link标记: /nodefaultlib {#A-link标记-x2F-nodefaultlib}

代表: Ignore all default libraries

包括运行时库, 都不用.

当然如果大家要用相关c运行时库的api 怎么办呢?
可以使用相关对应的API, 比如strcmpi, 使用lstrcmpi, 详细请参考下表:

| Standard function | Win32 equivalent | |-----------------------|--------------------------| | malloc | HeapAlloc | | free | HeapFree | | strcpy | lstrcpy | | strcat | lstrcat | | strncpy | lstrncpy | | strncat | lstrncat | | strlen | lstrlen | | strcmp | lstrcmp | | strcmpi | lstrcmpi | | memcpy | CopyMemory | | memset | FillMemory or ZeroMemory | | memmove | MoveMemory | | toupper | CharUpper | | tolower | CharLower | | isalpha | IsCharAlpha | | isalnum | IsCharAlphaNumeric | | islower | IsCharLower | | isupper | IsCharUpper | | sprintf | wsprintf | | vsprintf | wvsprint |

B. 设置连接节大小及其他 {#B-设置连接节大小及其他}

加入下面代码到cpp文件就可以.

|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #ifndef _DEBUG #pragma comment(linker, "/FILEALIGN:16") #pragma comment(linker, "/ALIGN:16") #pragma comment(linker, "/OPT:REF") #pragma comment(linker, "/OPT:ICF") #pragma comment(linker, "/OPT:NOWIN98") // 使用老VC编绎器的512大小为一节 // 合并段 #pragma comment(linker, "/MERGE:.rdata=.data") #pragma comment(linker, "/MERGE:.text=.data") #pragma comment(linker, "/MERGE:.reloc=.data") // Favour small code #pragma comment(linker, "/ENTRY:WinMain") #endif |

如果是少量代码的Exe 程序, 最终大小可以在1500 字节以内.
曾写过一个程序使用了文件读写, 执行进程, 字符运算, 等等一共50多行代码, 最终大小为: 1488字节.

C. 不幸的是可能还是要使用c运行库 {#C-不幸的是可能还是要使用c运行库}

那可以使用这个 LIBCTINY.LIB文件, 以尽量减小. 当然这个lib 本身包括不多的运行库api.
LIBCTINY.LIB 文件以及源程序参考:
http://msdn.microsoft.com/msdnmag/issues/01/01/hood/default.aspx

  1. 普通Dll 大小问题

因为: __DllMainCRTStartup 或: _DllMainCRTStartup 要调用运行时库
还好, LIBCTINY.LIB 里面已经有相关实现, 可以用LIBCTINY.LIB, 而不用调用运行库了. 这样可以大大减小.

连接设置:

|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #ifndef _DEBUG // default lib setting. #pragma comment(linker, "/defaultlib:kernel32.lib") #pragma comment(linker, "/defaultlib:LIBCTINY.LIB") #pragma comment(linker, "/nodefaultlib:libc.lib") #pragma comment(linker, "/nodefaultlib:libcmt.lib") // section size #pragma comment(linker, "/FILEALIGN:16") #pragma comment(linker, "/ALIGN:16") #pragma comment(linker, "/OPT:NOWIN98") // 合并段 #pragma comment(linker, "/MERGE:.rdata=.data") #pragma comment(linker, "/MERGE:.text=.data") #pragma comment(linker, "/MERGE:.reloc=.data") #endif |

另外我的测试程序中导出了一个接口

|-----------------|------------------------------------------------| | 1 2 3 4 | BOOL _stdcall ExpHook( ) { return 0; } |

最终大小为: 992字节.

  1. 复杂DLL和复杂EXE大小问题

如果你的程序一定要使用MFC, 那怎么编绎至少也有几十KB了.
但你还是可以用相关PE压缩程序压缩一下的. 至少能压缩到50%.

如果是COM, 建议不要使用MFC, 如果使用ATL, 可以使用压缩程序压缩一下, 基本会在20-40K 大小.

复杂类型的DLL, EXE肯定是要使用运行库的. 像用了ATL就没有办法不用运行库了.

参考链接:http://www.cppblog.com/weiym/archive/2012/07/07/182076.html


赞(2)
未经允许不得转载:工具盒子 » 如何减小EXE、DLL文件的大小