S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

优化C++程序编译效率的实例

Posted on 2012-02-26 16:40 S.l.e!ep.¢% 阅读(2086) 评论(0)  编辑 收藏 引用 所属分类: C++


标 题: 优化C++程序编译效率的实例
作 者:FlyToTheSpace
时 间:2005-12-27 22:12

链 接:http://bbs.pediy.com/showthread.php?threadid=19823


 

 

(1)自定义程序的入口
 (2)合并区段
 (3)不用调malloc,free等函数
 (3)不用cout来输出,cin来输入
 (4)如果调用了很多库函数如memset,stycpy等等
 的话,请导入msvcrt.lib,不然编译器会在程序里面
 导入静态库,这样的话程序就会大很多。。
 (5)window编程不用mfc...
 减少程序运行内存占用量可以调用
 SetProcessWorkingSetSize(GetCurrentProcess(),-1,-1);
 
----------sample.cpp---------------------
 #include <windows.h>
 #include "sample.h"
 #include "mydll.h"
 #include "resource.h"
 //这下面自定义函数入口
 #pragma comment(linker, "/ENTRY:EntryPoint")
 #pragma comment(linker,"/ALIGN:0x400")
 //设置区段属性,跟区段在内存起始地址
 //这里面要加写入的权限,不然程序就运行不了了
 //E为执行,R为可读,W为可写
 //更多的说明请参见msdn
 #pragma comment(linker,"/SECTION:.text,ERW /ALIGN:0x1000")
 //下面合并区段,
 #pragma comment(linker,"/merge:.data=.text")
 #pragma comment(linker,"/merge:.rdata=.text")
 //下面导入函数
 #pragma comment(lib,"mydll.lib")
 //下面是函数的入口
 //得到WinMain里面的几个参数
 //HINSTANCE hInstance=GetModuleHandle(NULL)
 //LPSTR lpCmdLine= GetCommandLine()
 //int nCmdShow  这个可以自己填
 void EntryPoint()
 {
   HINSTANCE hInstance;
   hInstance=GetModuleHandle(NULL);
   Sample pro(hInstance);
   DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,(DLGPROC)Sample::DialogProc,(LPARAM)&pro);
 }
 INT_PTR CALLBACK Sample::DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
   static Sample *pro;
   switch(message)
   {
   case WM_INITDIALOG:
     pro=(Sample *)lParam;
     pro->hwnd=hwnd;
     pro->Init();
     break;
   case WM_COMMAND:
     pro->WndPro_Command(wParam,lParam);
     break;
   case WM_CLOSE:
     pro->WndPro_Close();
     break;
   case WM_TIMER:
     //这里每秒钟触发一次
     //来减少内存占用量
                      //试着在任务管理器里面看一下,sample.exe内存占用量是不是只有200多k,在我这里是这样的
     if(wParam==100)
     {
       SetProcessWorkingSetSize(GetCurrentProcess(),
         -1,-1);
     }
     break;
   }
   return 0;
 }
 Sample::Sample(HINSTANCE hi)
 {
   this->hInstance=hi;
 }
 int Sample::WndPro_Command(WPARAM wParam,LPARAM lParam)
 {
   switch(wParam)
   {
   case IDOK:
     this->LoadDll();
     break;
   case IDCANCEL:
     this->WndPro_Close();
     break;
   }
   return 0;
 }
 int Sample::WndPro_Close()
 {
   EndDialog(hwnd,0);
   return 0;
 }
 int Sample::Init()
 {
   SetTimer(hwnd,100,100,NULL);
   return 0;
 }
 int Sample::LoadDll()
 {
   test(hwnd);
   return 0;
 }
 UINT malloc_(size_t num)
 {
   return (UINT)VirtualAlloc(NULL, num,MEM_RESERVE |MEM_COMMIT,PAGE_EXECUTE_READWRITE);
 }
 void free_(void * p)
 {
   VirtualFree(p,NULL,MEM_RELEASE);
 }
 void ZeroMem(char * mem,int len)
 {
   for(int i=0;i<len;i++)
     mem[i]=0;
 }
 -------------------------------
 ----------sample.h--------
 //下面是主函数的类
 class Sample
 {
 public:
   static INT_PTR CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
   Sample(HINSTANCE);
 private:
   HINSTANCE hInstance;
   HWND hwnd;
   int WndPro_Command(WPARAM,LPARAM);
   int WndPro_Close();
   int Init();
   int LoadDll();
 };
 ///-->下为精简的库函数
 //分配内存最好不用库函数malloc,
 //不要用cout 来输出
 //如果你调用了很多库函数的话
 //请在导入 msvcrt.lib
 UINT malloc_(size_t);//分配内存
 void free_(void *);//释放内存
 void ZeroMem(char *,int);//清零
 -------------------------------
 ---------mydll.cpp-----------
 #include <windows.h>
 #include "mydll.h"
 #pragma comment(linker, "/ENTRY:DllEntry")
 #pragma comment(linker,"/ALIGN:0x400")
 #pragma comment(linker,"/SECTION:.text,ERW /ALIGN:0x1000")
 #pragma comment(linker,"/merge:.data=.text")
 #pragma comment(linker,"/merge:.rdata=.text")
 BOOL APIENTRY DllEntry()
 {
   return 1;
 }
 INT APIENTRY test(HWND hwnd)
 {
   MessageBox(hwnd,"调用dll"," ",0);
   return 0;
 }
 -----------------------
 下面是程序完整的代码。。
附件:sample.rar


 

 

标 题: 答复
作 者:南蛮妈妈
时 间:2005-12-27 22:30

 


还能加些
 #pragma comment (linker, "/Filealign:0x200")
 #pragma comment (linker, "/OPT:REF")
 #pragma comment (linker, "/OPT:ICF")
 #pragma optimize("gsy", on)

 

 


标 题: 答复
作 者:FlyToTheSpace
时 间:2005-12-27 22:38

 


#pragma comment (linker, "/Filealign:0x200")
 在cl 里面,没这个选项。
 用下面这个,但是加了没用的,
 除非你的区段只有一个
 #pragma comment (linker, "/align:0x200")
 
下面的选项我还没用过,
 #pragma comment (linker, "/OPT:REF")
 #pragma comment (linker, "/OPT:ICF")
 #pragma optimize("gsy", on)
 我编译一般用命令行的,在.net 2003跟.net 2005
 里面的有好多选项连去都去不掉
 cl   mydll.cpp mydll.def /link /dll /out:mydll.dll /machine:x86 /subsystem:windows user32.lib kernel32.lib
 rc sample.rc
 cl sample.cpp /link /machine:x86  user32.lib kernel32.lib /subsystem:windows sample.res
 del sample.obj sample.res  mydll.obj mydll.exp
 pause

 

 


标 题:Re: 优化C++程序编译效率的实例
作 者:goldenegg
时 间:2005-12-28 10:08

 

 


引用:
--------------------------------------------------------------------------------
最初由 FlyToTheSpace 发布
(1)自定义程序的入口
(2)合并区段
(3)不用调malloc,free等函数
(3)不用cout来输出,cin来输入
(4)如果调用了很多库函数如memset,stycpy等等
........
--------------------------------------------------------------------------------

 


SetProcessWorkingSetSize只是给你感观上的内存变小而已,
如果你弄个hook进入photoshop这样的程序去做这件事,
你就会马上发现为什么别人并不怎么用 SetProcessWorkingSetSize

 SetProcessWorkingSetSize只是把内存写回磁盘,当用到时又要从磁盘加载回来,程序一大,内存量本身占用大,你次读写磁盘那么慢,你就会发现虽然内存占用量下去了,但是硬盘一真转个不停,程序基本上动不了...

所以如何节内存,不应从SetProcessWorkingSetSize下手,
当然现在你写的小程序可以例外.

其实如果有个界面,占用个1M的内存实在是小事,不必要去计较.

 

 


标 题: 答复
作 者:FlyToTheSpace
时 间:2005-12-28 11:54

 


SetProcessWorkingSetSize
这个我是跟踪realplay里面一个程序realsched.exe
发现的,其它减少内存用量的方法,还没找到

 对于那些大一点的程序,就不能用settimer每隔段时间调用,
 当程序的界面最小化时,调用一下就可以了,
 比如potoshop 在显示界面的时候,占用内存会很大,但只要你将它最小化
 内存占用量马上就减下来了,很多大一点的程序都是这样的。

 

 


标 题: 答复
作 者:dummy
时 间:2005-12-28 14:49

 


cl.exe 有许多关于程序代码优化的开关:
 /////////////////////////////////////////////////////////
                                -OPTIMIZATION-
 
/O1 minimize space      /Op[-] improve floating-pt consistency
 /O2 maximize speed      /Os favor code space
 /Oa assume no aliasing                   /Ot favor code speed
 /Ob<n> inline expansion (default n=0)    /Ow assume cross-function aliasing
 /Od disable optimizations (default)      /Ox maximum opts. (/Ogityb1 /Gs)
 /Og enable global optimization           /Oy[-] enable frame pointer omission
 /Oi enable intrinsic functions
 
                             -CODE GENERATION-
 
/G3 optimize for 80386                   /Gy separate functions for linker
 /G4 optimize for 80486                   /Ge force stack checking for all funcs
 /G5 optimize for Pentium                 /Gs[num] disable stack checking calls
 /G6 optimize for Pentium Pro             /Gh enable hook function call
 /GB optimize for blended model (default) /GR[-] enable C++ RTTI
 /Gd __cdecl calling convention           /GX[-] enable C++ EH (same as /EHsc)
 /Gr __fastcall calling convention        /Gi[-] enable incremental compilation
 /Gz __stdcall calling convention         /Gm[-] enable minimal rebuild
 /GA optimize for Windows Application     /EHs enable synchronous C++ EH
 /GD optimize for Windows DLL             /EHa enable asynchronous C++ EH
 /Gf enable string pooling                /EHc extern "C" defaults to nothrow
 /GF enable read-only string pooling      /QIfdiv[-] enable Pentium FDIV fix
 /GZ enable runtime debug checks          /QI0f[-] enable Pentium 0x0f fix

 

 


标 题: 答复
作 者:dwing
时 间:2005-12-28 15:59

 


我有中文版的编译器:
 
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
 Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
 
                          C/C++ 编译器选项
 
                              -优化-
 
/O1 最小化空间                          /Op[-] 改善浮点数一致性
 /O2 最大化速度                          /Os 优选代码空间
 /Oa 假设没有别名                        /Ot 优选代码速度
 /Ob<n> 内联展开(默认 n=0)               /Ow 假设交叉函数别名
 /Od 禁用优化(默认值)                    /Ox 最大化选项。(/Ogityb2 /Gs)
 /Og 启用全局优化                        /Oy[-] 启用框架指针省略
 /Oi 启用内部函数
 
                             -代码生成-
 
/G3 为 80386 进行优化                   /Gh 启用 _penter 函数调用
 /G4 为 80486 进行优化                   /GH 启用 _pexit 函数调用
 /G5 为 Pentium 进行优化                 /GR[-] 启用 C++ RTTI
 /G6 对 PPro、P-II、P-III 进行优化       /GX[-] 启用 C++ EH (与 /EHsc 相同)
 /G7 对 Pentium 4 或 Athlon 进行优化     /EHs 启用 C++ EH (没有 SEH 异常)
 /GB 为混合模型进行优化(默认)            /EHa 启用 C++ EH(w/ SEH 异常)
 /Gd __cdecl 调用约定                    /EHc extern "C" 默认为 nothrow
 /Gr __fastcall 调用约定                 /GT 生成纤维安全 TLS 访问
 /Gz __stdcall 调用约定                  /Gm[-] 启用最小重新生成
 /GA 为 Windows 应用程序进行优化         /GL[-] 启用链接时代码生成
 (按 <Enter> 继续)
 /Gf 启用字符串池                        /QIfdiv[-] 启用 Pentium FDIV 修复
 /GF 启用只读字符串池                    /QI0f[-] 启用 Pentium 0x0f 修复
 /Gy 分隔链接器函数                      /QIfist[-] 使用 FIST 而不是 ftol()
 /GZ 启用堆栈检查(/RTCs)                 /RTC1 启用快速检查(/RTCsu)
 /Ge 对所有函数强制堆栈检查              /RTCc 转换为较小的类型检查
 /Gs[num] 控制堆栈检查调用               /RTCs 堆栈帧运行时检查
 /GS 启用安全检查                        /RTCu 未初始化的本地用法检查
 /clr[:noAssembly] 为公共语言运行库编译
     noAssembly - 不产生程序集
 /arch:<SSE|SSE2> CPU 结构的最低要求,以下内容之一:
     SSE - 启用支持 SSE 的 CPU 可用的指令
     SSE2 - 启用支持 SSE2 的 CPU 可用的指令
 
                              -输出文件-
 
/Fa[file] 命名程序集列表文件            /Fo<file> 命名对象文件
 /FA[sc] 配置程序集列表                  /Fp<file> 命名预编译头文件
 /Fd[file] 命名 .PDB 文件                /Fr[file] 命名源浏览器文件
 /Fe<file> 命名可执行文件                /FR[file] 命名扩展 .SBR 文件
 /Fm[file] 命名映射文件
 
                              -预处理器-
 
/AI<dir> 添加到程序集搜索路径           /Fx 将插入的代码合并到文件
 (按 <Enter> 继续)
 /FU<file> 强制使用程序集/模块           /FI<file> 命名强制包含文件
 /C 不抽出注释                           /U<name> 移除预定义宏
 /D<name>{=|#}<text> 定义宏              /u 移除所有预定义宏
 /E 预处理到 stdout                      /I<dir> 添加到包含搜索路径
 /EP 预处理到 stdout,没有 #line         /X 忽略“标准位置”
 /P 预处理到文件
 
                                -语言-
 
/Zi 启用调试信息                        /Ze 启用扩展(默认)
 /ZI 启用“编辑并继续”调试信息          /Zl 省略 .OBJ 中的默认库名
 /Z7 启用旧式调试信息                    /Zg 生成函数原型
 /Zd 仅有行号调试信息                    /Zs 只进行语法检查
 /Zp[n] 在 n 字节边界上包装结构          /vd{0|1} 禁用/启用 vtordisp
 /Za 禁用扩展(暗指 /Op)                  /vm<x> 指向成员的指针类型
 /Zc:arg1[,arg2] C++ 语言一致性,这里的参数可以是:
     forScope - 对范围规则强制使用标准 C++
     wchar_t - wchar_t 是本机类型,不是 typedef
 
                              - 杂项 -
 
@<file> 选项响应文件                    /wo<n> 发出一次警告 n
 /?, /help 打印此帮助消息                /w<l><n> 为 n 设置警告等级 1-4
 /c 只编译,不链接                       /W<n> 设置警告等级(默认 n=1)
 (按 <Enter> 继续)
 /H<num> 最大外部名称长度                /Wall 启用所有警告
 /J 默认 char 类型是 unsigned            /Wp64 启用 64 位端口定位警告
 /nologo 取消显示版权消息                /WX 将警告视为错误
 /showIncludes 显示包含文件名            /WL 启用单行诊断
 /Tc<source file> 将文件编译为 .c        /Yc[file] 创建 .PCH 文件
 /Tp<source file> 将文件编译为 .cpp      /Yd 将调试信息放在每个 .OBJ 中
 /TC 将所有文件编译为 .c                 /Yl[sym] 为调试库插入 .PCH 引用
 /TP 将所有文件编译为 .cpp               /Yu[file] 使用 .PCH 文件
 /V<string> 设置版本字符串               /YX[file] 自动 .PCH
 /w 禁用所有警告                         /Y- 禁用所有 PCH 选项
 /wd<n> 禁用警告 n                       /Zm<n> 最大内存分配(默认为 %)
 /we<n> 将警告 n 视为错误
 
                                 -链接-
 
/MD 与 MSVCRT.LIB 链接                  /MDd 与 MSVCRTD.LIB 调试库链接
 /ML 与 LIBC.LIB 链接                    /MLd 与 LIBCD.LIB 调试库链接
 /MT 与 LIBCMT.LIB 链接                  /MTd 与 LIBCMTD.LIB 调试库链接
 /LD 创建 .DLL                           /F<num> 设置堆栈大小
 /LDd 创建 .DLL 调试库                   /link [链接器选项和库]

 

 


标 题:Re: 优化C++程序编译效率的实例
作 者:dwing
时 间:2005-12-28 16:49

 


楼主的文章写的不错!
 但标题写的有点疑虑.
 因为优化有几种意义:速度优化,代码空间优化,编译速度优化和内存占用优化.
 一般来说需要速度优化的地方,代码空间优化和内存占用优化就要牺牲一些.
 
编译速度优化可能意义不太大,不过我还是补充一下:
 例如添加以下宏可以提高一些编译速度,在硬盘和CPU速度较慢的机器上尤为明显.
 #define VC_EXTRALEAN
 #define WIN32_LEAN_AND_MEAN
 #define WIN32_EXTRA_LEAN
 另外如果关闭预编译头文件的功能,可以大大提高第一次编译的速度,并减少硬盘占用的空间.
 强烈建议编译小程序的时候关闭这个功能,因为它默认是启动的.
 
下面评价一下楼主的一些优化,仅供参考.
 


引用:
--------------------------------------------------------------------------------
(1)自定义程序的入口
--------------------------------------------------------------------------------

 

 一般不建议使用自定义入口,虽然只有使用动态库时只节省不到1KB.
 主要是考虑到C++的全局对象的构造,如果自定义就会被忽略掉.
 不过如果确实想使代码精简到极限,可以考虑.
 此优化对速度几乎无影响.
 


引用:
--------------------------------------------------------------------------------
(2)合并区段
--------------------------------------------------------------------------------

 

 这一项对减小PE文件大小很有帮助,但一定要注意正确设置好节(段)属性,否则后果不可知.
 表面上此优化对速度无影响,但可能会导致数据cache与代码cache重叠,不利于CPU的执行.
 如果需要加压缩壳,此优化可能无效,如果合并不当可能还会使压缩能力降低(例如代码被混合在数据当中).
 


引用:
--------------------------------------------------------------------------------
(3)不用调malloc,free等函数
--------------------------------------------------------------------------------

 

 分配内存不用malloc,free等函数用什么?new和delete吗?后者当然更好:)
 Win32API有众多分配内存的函数,malloc等C/C++标准库当然使用的是API中的
 堆分配(HeapAlloc),而堆分配调用虚拟分配(VirtualAlloc).效率当然是后者高一些.
 但实际内存分配一般在初始化过程中使用,而且使用次数也不应过多(以避免内存碎片).
 所以速度影响几乎可忽略.
 代码量应该不会有太大影响.
 


引用:
--------------------------------------------------------------------------------
(3)不用cout来输出,cin来输入
--------------------------------------------------------------------------------

 

 这个确实可以使用C标准库来替代,而且使用灵活,速度更快一些.
 如果使用动态库,代码量差距不大.
 


引用:
--------------------------------------------------------------------------------
(4)如果调用了很多库函数如memset,stycpy等等的话,请导入msvcrt.lib,
 不然编译器会在程序里面导入静态库,这样的话程序就会大很多。。
--------------------------------------------------------------------------------

 

 这点不用担心了.原因如下:
 如果使用最快速度优化,memset,stycpy,sin等某些内存/字符串/数学函数会被自动内联到程序中,
 无论是否使用动态库还是静态库,速度要快的多,我也推荐这么做.
 使用次数过多代码量会大一些.但如果加压缩壳的话影响不会太大.
 如果使用最小代码优化,自动内联的函数不会内联,此时可使用动态库以减小代码量.
 如果只使用1~2次某个可自动内联的函数的话代码量可能反而更多(还要考虑到导入表)
 


引用:
--------------------------------------------------------------------------------
(5)window编程不用mfc...
--------------------------------------------------------------------------------

 

 呵呵,这就不一定了.目前如果没有还在使用Win95系统的话,MFC的动态库就可以大胆使用了.
 但要注意一定要使用MFC42.DLL的库,也就是VC6.0自带的库,高版本的可能连WinXP也不会自带.
 


引用:
--------------------------------------------------------------------------------
减少程序运行内存占用量可以调用SetProcessWorkingSetSize(GetCurrentProcess(),-1,-1);
--------------------------------------------------------------------------------

 

 又学到一招!
 但我不得不说一下:这是个骗人的招数.拿来骗一骗初级用户还可以-_-
 因为任务管理器只显示进程当前使用的物理内存大小,所以使用这个招数虽然可以降低物理内存占用.
 但虚拟内存并无减少,所以这个技巧只建议使用在后台或很少工作的进程.
 经常使用这个函数会造成CPU负担过重,磁盘交换文件的读写也会更频繁.这样会很影响进程的执行效率.
 其实不需要在意物理内存占用,如果物理内存不够用,系统会自动降低不常工作的进程的物理内存.

 

 


标 题: 答复
作 者:dwing
时 间:2005-12-28 17:05

 


再补充几点:


引用:
--------------------------------------------------------------------------------
#pragma comment (linker, "/align:0x200")
--------------------------------------------------------------------------------

 

 这着我也经常用,不过我经常这么写(只用于VC6.0):
 #pragma comment(linker,"/OPT:NOWIN98")
 但是如果要加压缩壳的话,这个PE文件空间优化没有一点作用,
 因为虚拟地址没有改变(仍然是4KB,而且无法改变).
 


引用:
--------------------------------------------------------------------------------
#pragma comment (linker, "/ALIGN:16")
--------------------------------------------------------------------------------

 

 对齐到16字节可能有兼容性问题,可能不能在Win9x中运行.
 


引用:
--------------------------------------------------------------------------------
#pragma comment(linker, "/ENTRY:EntryPoint")
--------------------------------------------------------------------------------

 

 如果没有不加入默认库的话可以不用自定义入口.
 而直接用void mainCRTStartup()或void WinMainCRTStartup()即可.
 但不使用默认库可能某些浮点数的转换会出现问题,虽然可以使用其他方法解决.
 


引用:
--------------------------------------------------------------------------------
#pragma comment (linker, "/OPT:REF")
 #pragma comment (linker, "/OPT:ICF")
--------------------------------------------------------------------------------

 

 这一项其实在默认的优化编译设置中已经有了,不用写出来.
 如果启动"/OPT:REF"的话,"/OPT:ICF"默认会自动启动.
 


引用:
--------------------------------------------------------------------------------
#pragma comment (linker,"/merge:.rsrc=.text")
--------------------------------------------------------------------------------

 

 这项一定不要加,有时候如果资源不在某个节(段)的开始,程序的图标可能不能显示出来.

 

 


标 题: 答复
作 者:goldenegg
时 间:2005-12-29 21:13

 

 


引用:
--------------------------------------------------------------------------------
最初由 FlyToTheSpace 发布
 SetProcessWorkingSetSize
 这个我是跟踪realplay里面一个程序realsched.exe
 发现的,其它减少内存用量的方法,还没找到
 
对于那些大一点的程序,就不能用settimer每隔段时间调用,
 ........
--------------------------------------------------------------------------------

 

 nono,不是大的程序自己搞的,是操作系统做的。
 在你的窗口最小化的时候,操作系统自动帮你把内存最小化了。
 所以,你自己就更没有必要去调这个函数了。
 


引用:
--------------------------------------------------------------------------------
最初由 dwing 发布
 
呵呵,这就不一定了.目前如果没有还在使用Win95系统的话,MFC的动态库就可以大胆使用了.
 但要注意一定要使用MFC42.DLL的库,也就是VC6.0自带的库,高版本的可能连WinXP也不会自带.
 
--------------------------------------------------------------------------------

 

nono,mfc42.dll从win98se开始,到longhorn都是默认有的。vc6 mfc的程序,编成release就可以在每台机器上跑了,不用到处拷个mfc42.dll

 

 


标 题: 答复
作 者:dwing
时 间:2005-12-30 15:38

 

 


引用:
--------------------------------------------------------------------------------
最初由 goldenegg 发布
 nono,mfc42.dll从win98se开始,到longhorn都是默认有的。vc6 mfc的程序,编成release就可以在每台机器上跑了,不用到处拷个mfc42.dll
 ........
--------------------------------------------------------------------------------

 

 可能是对我的话理解有误.我们的观点是一样的.
 再补充一下:
 Win95OSR2(Win97)虽然自带msvcrt40.dll和mfc30.dll,但不是目前的标准库了.
 Win98SE自带了msvcrt.dll和mfc42.dll,Win98第一版不知有没有.
 WinXP第一版肯定不带msvcr71.dll和mfc71.dll,这些是VC7.1才使用的动态库.


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理