从VC6.0向2008转换的问题
VC6.0编译常见错误的详解及其错误分析(范文)

VC6.0编译常见错误的详解及其错误分析(范文)第一篇:VC6.0编译常见错误的详解及其错误分析(范文)VC6.0编译常见错误第一部分编译错误1. error C2001: newline in constant编号:C2001直译:在常量中出现了换行。
错误分析:(1)字符串常量、字符常量中是否有换行。
(2)在这句语句中,某个字符串常量的尾部是否漏掉了双引号。
(3)在这语句中,某个字符创常量中是否出现了双引号字符““”,但是没有使用转义符“””。
(4)在这句语句中,某个字符常量的尾部是否漏掉了单引号。
(5)是否在某句语句的尾部,或语句的中间误输入了一个单引号或双引号。
2. error C2015: too many characters in constant编号:C2015直译:字符常量中的字符太多了。
错误分析:单引号表示字符型常量。
一般的,单引号中必须有,也只能有一个字符(使用转义符时,转义符所表示的字符当作一个字符看待),如果单引号中的字符数多于4个,就会引发这个错误。
另外,如果语句中某个字符常量缺少右边的单引号,也会引发这个错误,例如:if(x == 'x || x == 'y'){ … }值得注意的是,如果单引号中的字符数是2-4个,编译不报错,输出结果是这几个字母的ASC码作为一个整数(int,4B)整体看待的数字。
两个单引号之间不加任何内容会引发如下错误:error C2137:empty characterconstant。
3. error C2018: unknown character '0x##'编号:C2018直译:未知字符‘0x##’。
错误分析:0x##是字符ASC码的16进制表示法。
这里说的未知字符,通常是指全角符号、字母、数字,或者直接输入了汉字。
如果全角字符和汉字用双引号包含起来,则成为字符串常量的一部分,是不会引发这个错误的。
VC++6.0转到VS2008常出现的错误及解决方案

刚从VC++6.0转到VS2008,用着好不习惯,网上找到一帖子,转给大家,希望会有帮助。
--------------------------------------------------------------------------------------------------首先在此引一例子当源文件由vc++6.0转到vs2008时会出现如下错误:错误一:error C2039: 'WriteHuge' : is not a member of 'CFile'"解决方案:只有VC6有函数WriteHuge,VC7以上就没有了。
用Write替换WriteHuge就可以解决问题。
1.MessageBox()VC++6.0:MessageBox("Hello,World!");VS2008:MessageBox(L"Hello,World!"); 或MessageBox(TEXT("Hello,World!"));bo box内容添加方法VC++6.0:Drop-Down List Box Control 的Properties 中的Data 用Ctrl-Enter 输入VS2008:更名为Combo-Box Control ,并在右侧Data 区域用semicolons(即';')分隔输入3.从.net开始就没有classwizard了,全部在属性窗口里了属性窗口中有,闪电图标及右边的都是,包括事件,消息,虚函数重载,加入变量则是在类标上右击->添加变量……4.消息映射VS2005对消息的检查更为严格,以前在VC6下完全正常运行的消息映射在VS2005下编译不通过a,ON_MESSAGE(message,OnMyMessage);OnMyMessage返回值必须为LRESULT,其形式为:afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);如果不符合,则有错误提示:error C2440: “static_cast”: 无法从“void (__thiscall CPppView::* )(WPARAM,LPARAM)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”error C2440: “static_cast”: 无法从“void (__thiscall CPppView::* )(void)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”b,在VS2005中,OnMyMessage返回值必须为BOOL,且含有一个UINT 参数指出了命令ID,其形式为:afx_msg BOOL OnMyMessage(UINT);如果不符合,则有错误提示.如在VS6中,OnMyMessage2的定义为afx_msg BOOL OnViewZoomBar()时亦可正常编译通过,但在VS2005下,有错误提示:error C2440: “static_cast”: 无法从“BOOL (__thiscall CMainFrame::* )(void)”转换为“BOOL (__thiscall CCmdTarget::* )(UINT)”error C2440: “static_cast”: 无法从“BOOL (__thiscall CMainFrame::* )(void)”转换为“BOOL (__thiscall CCmdTarget::* )(UINT)”5.字符处理在c中广泛使用的strcpy,strcat,strstr等等推荐使用更为安全strcpy_s,strcat_s,strstr_s等来代替.6.数学函数检查VS2005中,数学函数的参数检查更为严格,如pow(2, 45)会引起一个错误提示如下:error C2668: “pow”: 对重载函数的调用不明确d:program filesmicrosoft visual studio 8vcincludemath.h(575): 可能是“long double pow(long double,int)”d:program filesmicrosoft visual studio 8vcincludemath.h(527): 或“float pow(float,int)”d:program filesmicrosoft visual studio 8vcincludemath.h(489): 或“double pow(double,int)”试图匹配参数列表“(int, int)”时正确的使用为pow(2.0, 45)7.更加符合C++标准如在VS6中,在FOR循环中的循环变量的定义的作用域延伸到循环体外,VS2005则修正了这样的bug。
vc6.0迁移到vs2010中的问题的解决方法

1.编译错误C20651>c:¥documents and settings¥administrator¥桌面¥host_sp3¥selectdialog.cpp(62): errorC2065: “i”: 未声明的标识符解决办法,将for (int i = 0; i < m_deviceList.size(); i++){m_ctlDevicelist.AddString(m_deviceList[i]);}中变量i的定义放到函数体开头int i;for (i = 0; i < m_deviceList.size(); i++){m_ctlDevicelist.AddString(m_deviceList[i]);}2.链接错误LNK2019odbccp32.lib(dllload.obj) : error LNK2019: 无法解析的外部符号__imp___vsnprintf,该符号在函数_StringVPrintfWorkerA@20 中被引用odbccp32.lib是在程序中对数据库操作时用到的,这个链接问题在使用静态DLL方式时才会遇到,如果使用共享DLL方式时不会出现,但是因为本程序需要使用静态DLL方式,所以继续尝试其他的解决方法。
尝试在程序属性的连接器输入选项中添加附加依赖项odbccp32.lib,依然报错。
于是在系统中搜索这个lib文件,最终找到了两种不同版本的odbccp32.lib。
VC6.0中文件信息:C:¥Program Files¥Microsoft Visual Studio¥VC98¥Lib¥ODBCCP32.LIBVS2010中文件信息:C:¥Program Files¥Microsoft SDKs¥Windows¥v7.0A¥Lib¥odbccp32.lib从文件信息中可以看出两个文件的版本大小都不同。
2008迁移部署

• WinSxS文件夹
WinSxS是VISTA/Windos 2008/Windows 7的 Windows目录下一个非常重要的文件夹,该文件夹里 边有很多重要的组件,版本也很复杂,为了保证 Windows的正常运行,里面的文件是不可删除的。 微软关于WinSxS的说明是为了支持COM和共享 DLL的隔离,减少因为动态链接库(Dynamic Link Libraries,DLL)引起的配置问题
• WinSxS文件夹的所有者
如果只是将网管部署到XP/2003等系统上,我们 这里完全可以将运行时库相关的文件(包括DLL库、 manifest文件、policy文件)抠出来,直接放到安装包 里来部署。 WinSxS文件夹在VISTA/Windos 2008/Windows 7 默认的所有者是:TrustedInstaller,他是不允许我们 的网管包直接往WinSxS文件夹及其子文件夹下面筛 东西的。这样的网管包在如上系统上安装时,会提示 出错并退出安装。
• 应用程序的Manifest清单文件
在构建网管应用程序的时候,也会得到各个模块 相应的manifest清单文件。 比如a.exe或b.dll,对应的清单文件为 a.exe.intermediate.manifest b.dll.intermediate.manifest 但是我们注意到发布时并没有将这些清单文件一 同打包到网管安装包中,这是因为在构建的时候会默 认将manif清单文件
manifest清单文件是vc2005/vc2008采用的新的程 序部署技术,它定义了程序运行的依赖关系(程序运 行所需要的dll库的名称、版本等)。 所在的系统中如果没有程序运行所需要的dll库 和相应的manifest清单文件,则会弹出“应用程序配 应用程序配 置不正确,程序无法启动”对话框。 置不正确,程序无法启动
VC6.0常见错误信息分析

1.程序开发过程中出现的错误类型我们在进行程序设计时,不可避免地会犯错误。
程序中的错误可以分为三类:编译错误、运行时错误和逻辑错误。
1.1编译错误编译错误(Compile errors)又称为编译时错误(Compiling-time errors): 是由于错误的编码产生的。
例如关键字拼写错误、将中文标点符号当成英文符号使用、遗漏了某些必要的标点符号或者使用了一个没有定义的标识符。
编译错误一般都是语法错误,当编译器对程序进行语法检查时,都能发现这些错误,并能够指出产生错误的位置(标出行号)。
我们可以根据编译出错信息指出的行号找到对应的源代码行改正错误,重新编译源程序。
只有当所有的编译错误被改正后,才能通过编译检查,产生目标代码文件。
改正编译错误的关键是要能正确理解编译器给出的编译错误信息。
VC++环境中的编译、链接错误信息是用英文表示的。
对于英文基础薄弱的读者,可以参考本实验指导书后面的“VC++编译、链接常见错误和警告信息中英文对照”。
通常情况下,一个语法错误可能产生多条编译错误信息,这是由于株连错误造成的,建议读者在处理编译错误时,找到第一个出现错误的位置改正后重新编译。
这样能够避免被株连错误迷惑。
值得指出的是,现在大部分编译器对错误的定位不精确,如果在编译器指出的行没有发现错误,应该向前查找错误。
例如,当提示第10行发生错误时,如果在第10行没有发现错误,请从第10行开始往前查找错误并修改之。
1.2运行时错误运行时错误(Run-time errors)是在程序的运行阶段出现的,当运行环境检测到程序的某些操作无法执行,例如除数为零时,就会出现运行时错误。
当运行环境检测到程序的某些操作是被禁止的,也会产生运行时错误。
例如,访问数组时超越数组的边界,空指针引用(NULL pointer assignment,空指针赋值,即有指针未赋具体地址就使用了)等等。
1.3逻辑错误逻辑错误(Logic errors):当程序没有按照程序员的意图执行时,就表明程序中存在逻辑错误。
VC++6.0与VS2008的区别

1.MessageBox()VC++6.0:MessageBox("Hello,World!");VS2008:MessageB ox(L"Hello,World!"); 或MessageBox(TEXT("Hello,World!"));bo box内容添加方法VC++6.0:Drop-Down List B ox Control 的Properties 中的Data 用Ctrl-Enter 输入VS2008:更名为Combo-Box Control ,并在右侧Data 区域用semicolons(即';')分隔输入3.从.net开始就没有classwizard了,全部在属性窗口里了属性窗口中有,闪电图标及右边的都是,包括事件,消息,虚函数重载,加入变量则是在类标上右击->添加变量……4.消息映射VS2005对消息的检查更为严格,以前在VC6下完全正常运行的消息映射在VS2005下编译不通过a,ON_MESSAGE(message,OnMyMessage);OnMyMessage返回值必须为LRESULT,其形式为:afx_msg LRESULT OnMyMessage(WPAR AM, LPARAM);如果不符合,则有错误提示:error C2440: “static_cast”: 无法从“void (__thiscall CPppView::* )(WPARAM,LPARAM)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”error C2440: “static_cast”: 无法从“void (__thiscall CPppView::* )(void)”转换为“LRESULT (__t hiscall CWnd::* )(WPARAM,LPARAM)”b,在VS2005中,OnMyMessage返回值必须为BOOL,且含有一个UINT 参数指出了命令ID,其形式为:afx_msg BOOL OnMyMessage(UINT);如果不符合,则有错误提示.如在VS6中,OnMyMessage2的定义为afx_msg BOOL OnViewZoomBar()时亦可正常编译通过,但在VS2005下,有错误提示:error C2440: “static_cast”: 无法从“BOOL (__thiscall CMainFrame::* )(void)”转换为“BOOL (__thiscall CCmdTarget::* )(UINT)”error C2440: “static_cast”: 无法从“BOOL (__thiscall CMainFrame::* )(void)”转换为“BOOL (__thiscall CCmdTarget::* )(UINT)”5.字符处理在c中广泛使用的strcpy,strcat,strstr等等推荐使用更为安全strcpy_s,strcat_s,strstr_s等来代替.6.数学函数检查VS2005中,数学函数的参数检查更为严格,如pow(2, 45)会引起一个错误提示如下:error C2668: “pow”: 对重载函数的调用不明确d:\program files\microsoft vi sual studio 8\vc\include\math.h(575): 可能是“long double pow(long double,int)”d:\program files\microsoft vi sual studio 8\vc\include\math.h(527): 或“float pow(float,int)”d:\program files\microsoft vi sual studio 8\vc\include\math.h(489): 或“double pow(double,int)”试图匹配参数列表“(int, int)”时正确的使用为pow(2.0, 45)7.更加符合C++标准如在VS6中,在FOR循环中的循环变量的定义的作用域延伸到循环体外,VS2005则修正了这样的bug。
VC6与VS2008类型转换

VC6.0与VS2008数据类型转换问题UNICODE计算机发明后,为了在计算机中表示字符,人们制定了一种编码,叫ASCII码。
ASCII码由一个字节中的7位(bit)表示,范围是0x00 - 0x7F 共128个字符。
他们以为这128个数字就足够表示abcd....ABCD....1234 这些字符了。
咳......说英语的人就是“笨”!后来他们突然发现,如果需要按照表格方式打印这些字符的时候,缺少了“制表符”。
于是又扩展了ASCII的定义,使用一个字节的全部8位(bit)来表示字符了,这就叫扩展ASCII 码。
范围是0x00 - 0xFF 共256个字符。
咳......说中文的人就是聪明!中国人利用连续2个扩展ASCII码的扩展区域(0xA0以后)来表示一个汉字,该方法的标准叫GB-2312。
后来,日文、韩文、阿拉伯文、台湾繁体(BIG-5)......都使用类似的方法扩展了本地字符集的定义,现在统一称为MBCS 字符集(多字节字符集)。
这个方法是有缺陷的,因为各个国家地区定义的字符集有交集,因此使用GB-2312的软件,就不能在BIG-5的环境下运行(显示乱码),反之亦然。
咳......说英语的人终于变“聪明”一些了。
为了把全世界人民所有的所有的文字符号都统一进行编码,于是制定了UNICODE标准字符集。
UNICODE 使用2个字节表示一个字符(unsigned shor int、WCHAR、_wchar_t、OLECHAR)。
这下终于好啦,全世界任何一个地区的软件,可以不用修改地就能在另一个地区运行了。
虽然我用IE 浏览日本网站,显示出我不认识的日文文字,但至少不会是乱码了。
UNICODE 的范围是0x0000 - 0xFFFF 共6万多个字符,其中光汉字就占用了4万多个。
嘿嘿,中国人赚大发了:0)在程序中使用各种字符集的方法:const char * p = "Hello"; // 使用ASCII 字符集const char * p = "你好"; // 使用MBCS 字符集,由于MBCS 完全兼容ASCII,多数情况下,我们并不严格区分他们LPCSTR p = "Hello,你好"; // 意义同上const WCHAR * p = L"Hello,你好"; // 使用UNICODE 字符集LPCOLESTR p = L"Hello,你好"; // 意义同上// 如果预定义了_UNICODE,则表示使用UNICODE字符集;如果定义了_MBCS,则表示使用MBCSconst TCHAR * p = _T("Hello,你好");LPCTSTR p = _T("Hello,你好"); // 意义同上在上面的例子中,T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用MBCS,也不明确表示使用UNICODE。
VC++6.0版本程序转成VS2010版

VC++6.0版本程序转成VS2010版直接转换的时候遇到两个问题:1、预编译头文件*.PCH找不到2、static_cast”: 无法从“void (__thiscall CView2::* )(void)”转换为“LRESULT (__thiscallCWnd::* 1、来源:/archives/2231错误:fatal error C1083: 无法打开预编译头文件:“Debug\xxx.pch”: No such file or directory“Rebuild All”没有解决,然后把“C/C++”属性中的“预编译头”由“使用(/Yu)”改为“创建(/Yc)”,问题解决了。
看来还是预编译头文件xxx.pch创建的有问题,仔细想一下,vc工(其实起作用的是stdafx.h,但头文件不参加编译,程的预编译头是由stdafx.cpp编译生成的。
所以需要stdafx.cpp文件,这个文件里只有一句代码:#include “Stdafx.h”。
)综上:最妥善的解决方法就是,在工程属性中,选择“使用(/Yu)”预编译头,而单独将stdafx.cpp设置为“创建(/Yc)”预编译头。
关于“预编译头”的作用,参考如下:在很多程序中,每个源文件都存在一些相同的部分。
比如要包含相同的一些头文件,而且这些头文件可能很长,例如window.h。
如果用普通的方法编译这些源文件,对这些头文件在每个源文件中的出现都要重新编译,作了很多重复工作。
如果能将这些头文件专门进行编译,并且把结果存储起来。
然后在编译包含这些头文件的源文件时,使用上述结果替代头文件在源文件中的出现,就可以大大减少工作量。
Microsoft Visual C++提供的“预编译头文件”机制就支持这一功能。
所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常以.pch为扩展名),这个文件就称为预编译头文件。
这些预先编译好的代码可以是任何的C/C++代码——–甚至是inline的函数,但必须是稳定的,在工程开发的过程中不会被经常改变。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
首先可以直接用Visual Studio 2008的打开VC6的工作区文件和项目文件(dsw和dsp),并将其升级为VS2008的解决方案格式和项目格式(sln和vcproj),VC9的编译器相对于VC6有了很大的变化,一些编译参数和链接参数被废弃(比如/map:line),有一些改变了名称,还有新增的选项,不过不用担心,升级过程会自动对其进行转换,最终都会得到一个正确的解决方案和VC项目文件,这个过程不会遇到太多的麻烦,问题都出在随后的编译过程中,下面就将我在移植的过程中遇到的问题和我的解决方法总结一下,希望对还在用VC6维护代码的朋友有所帮助。
一、_WIN32_WINNT 与_WIN32_IE 设置冲突_WIN32_WINNT 与_WIN32_IE设置不兼容会导致如下C1189致命错误:StdAfx.cppc:\program files\microsoft sdks\windows\v6.0a\include\sdkddkver.h(217) : fatal error C1189: #error : _WIN32_WINNT settings conflicts with _WIN32_IE settingStdAfx.cpp通常是项目中第一个编译的文件,这个错误将导致编译无法继续进行。
产生这个错误的原因是原因是_WIN32_WINNT的版本定义太老,老的VC代码对_WIN32_WINNT 的典型设置是:#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif0x0400相对于VS2008所带的Plarform SDK(在文件sdkddkver.h中)中_WIN32_IE的定义来说太老了,导致不兼容,可以将其改成0x0501或更高的版本避免这个问题,如下所示:#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0501#endif也可以将这三行_WIN32_WINNT定义删除,这样就会使用Plarform SDK中的_WIN32_WINNT定义,自然就不存在不兼容问题了。
不过出于对老版本VC的兼容考虑(毕竟以后可能还要使用VC6编译代码),最好这样修改:#if _MSC_VER <= 1200 // MFC 6.0 or earlier#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400#endif#endif二、afximpl.h文件中的语法错误MFC出现的时候STL还没有成为C++的标准,所以MFC使用一套自己的模版库,比如CArray、CList、CMap等等,这些类型声明都在afximpl.h文件中。
原来在VC6编译器适用的模版语法可能不适用VC9,特别是当以下四个环境变量设置不兼容时,就会出现这个编译错误,大致情况如下:e:\software\microsoft visual studio 9.0\vc\atlmfc\src\mfc\afximpl.h(625) : error C2059: syntax error : '<L_TYPE_raw>'e:\software\microsoft visual studio 9.0\vc\atlmfc\src\mfc\afximpl.h(625) : error C2238: unexpected token(s) preceding ';'e:\software\microsoft visual studio 9.0\vc\atlmfc\src\mfc\afximpl.h(629) : error C2059: syntax error : '<L_TYPE_raw>'e:\software\microsoft visual studio 9.0\vc\atlmfc\src\mfc\afximpl.h(629) : error C2238: unexpected token(s) preceding ';'合理调整stdafx.h中WINVER、_WIN32_WINNT、_WIN32_WINDOWS和_WIN32_IE的设置可以避免这个问题,将三个与Windows版本有关的环境变量设置为0x0501或更高版本,将IE版本的环境变量设置为0x0500以后的版本就可以解决这个问题。
当然,考虑到与旧的VC6代码兼容,可以采用上一个问题中提到的最后一个解决办法,用_MSC_VER进行隔离。
三、旧的CRT库和新的安全CRT库引起的C4996告警解决了环境变量设置不匹配导致的问题后,编译过程就真正开始了,不过首先映入眼帘的应该是成堆的C4996编译告警,对每个使用了含字符串参数的CRT库函数都会有C4996编译告警,一个典型的输出如下所示:f:\project\.....\commonfunc.cpp(280) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_W ARNINGS. See online help for details.e:\software\microsoft visual studio 9.0\vc\include\string.h(74) : see declaration of 'strcpy'MSDN online 是这样解释的:为了显著增加CRT库的安全性,许多CRT函数都有了一个更安全的新版本,新版本和旧版本的区别就是新版本函数名多了一个_s后缀。
只要一个CRT 函数有新的安全版本,编译器就会产生一个C4996告警,不过,出现这个告警的目的并不是说旧版本的CRT函数将淡出CRT库,告警出现只是为了提醒程序员这个函数有更安全的版本存在。
一种安全的或者是被鼓励的做法是用安全版本的函数替换现有的CRT函数,不过对于一个有相当代码量的项目,替换工作量也是巨大的,这可不是用名称查找、替换就能简单解决的问题,因为许多安全版本的CRT函数参数个数也发生了变化。
也可以用预处理指令消除这个告警:#pragma warning( disable : 4996 )或者定义_CRT_SECURE_NO_W ARNINGS 压制这个告警(在stdafx.h中define或在项目属性中设置预处理符号,PreProcessor Definitions)。
除了C语言的CRT函数外,POSIX 兼容函数也存在这个告警,解决方法是用POSIX标准名称替换(比如access换成_access)或者是定义_CRT_NONSTDC_NO_W ARNINGS 压制这个告警(方法同上)。
四、“CWinApp::Enable3dControls”引起的C4996告警这个是编译使用了老的向导生成的MFC代码时遇到的问题,一个典型的告警信息输出如下所示:CrpFileCrack.cppf:\project\.....\crpfilecrack.cpp(52) : warning C4996: 'CWinApp::Enable3dControls': CWinApp::Enable3dControls is no longer needed. You should remove this call.e:\software\microsoft visual studio 9.0\vc\atlmfc\include\afxwin.h(4818) : see declaration of 'CWinApp::Enable3dControls'通常向导生成的代码是:#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL#elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endif这两个函数的调用是旧的MFC版本对新版本的操作系统特性的支持,在新的(那个时候是新的)Windows 95平台上要这样调用一下才能使用新的Windows 3D样式的控件,否则就是老的Win 3.2样子的控件。
想当初喜欢OWL就是因为感觉它的控件比较“酷”,比如那个带底纹的对话框,菱形的checkbox,还有带图标的“OK”按钮,看到MFC作出来的灰灰的界面就觉得土,不过后来就知道MFC做界面也是很漂亮的,比如我做的。
,再打住。
对于新的MFC版本来说已经不需要再调用这两个函数了,参考前面的方法,用_MSC_VER 对其隔离就行了:#if _MSC_VER <= 1200 // MFC 6.0 or earlier#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL#elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endif#endif五、.def文件引起的连接告警对于普通的DLL项目中使用的.def文件通常会引起LNK4017链接告警,如下所示:.\ComFunc.def(4) : warning LNK4017: DESCRIPTION statement not supported for the target platform; ignoredCreating library .\..\Debug/ComFunc.lib and object .\..\Debug/ComFunc.exp一个典型的.def文件通常有以下内容:LIBRARY "XorCryptor"DESCRIPTION 'XorCryptor Windows Dynamic Link Library'EXPORTS; Explicit exports can go here..................消除这个连接告警的方法就是从.def文件中删除DESCRIPTION描述信息,不过这个告警也不是什么大问题,不删也可以。