VC6.0 环境下的大型项目(包括MFC)移植到 vs2010 环境的问题总结

来源:互联网 发布:信知汉王畏恶其能翻译 编辑:程序博客网 时间:2024/06/16 21:50

前言

本人由于刚刚参加实习工作,而到公司实习的第一个任务就是将公司现有的产品(铁路信号集中检测----终端系统)从vc6.0的开发环境移植到vs2010上。
这款系统是十几年前写的,期间虽然改动了很多次,但是始终都是遵循的老版本的标准。到现在随着开发的难度不断增加,所以把这个任务交给了我。
此篇文章主要记录的是我在修改系统期间所遇到的一些问题,和我最后解决的方法。但是有些东西设计到业务上的机密,所以可能不是很全面。就只能最为以后有人需要做这样工作的人提供一个参考而已。如果有什么问题,的可以直接私信我。这是我第一次写博客,可能写的不是很好,还希望大家多多指正。
好了不废话了,大家看正文把。

编译阶段error

一、_WIN32_WINNT 与 _WIN32_IE 设置冲突
_WIN32_WINNT  _WIN32_IE设置不兼容会导致如下C1189致命错误:

StdAfx.cpp
c:/program files/microsoft sdks/windows/v6.0a/include/sdkddkver.h(217) : fatalerror C1189: #error : _WIN32_WINNT settings conflicts with _WIN32_IE setting

StdAfx.cpp
通常是项目中第一个编译的文件,这个错误将导致编译无法继续进行。产生这个错误的原因是原因是_WIN32_WINNT的版本定义太老,老的VC代码对_WIN32_WINNT的典型设置是:

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

0x0400
相对于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


上面的摘自:https://wenku.baidu.com/view/12b47506f8c75fbfc67db295.html?from=search


二、VS2010中,数学函数的参数检查更为严格,

如)fabs(45)、pow等数学函数会引起一个错误提示如下:

error C2668: “pow”: 对重载函数的调用不明确(类似问题相同)

解决方法:把参数类型强转。将参数进行加上(.0)如:pow(3,i) ->pow(3.0,i),

 

三、for 语句的变量作用域问题

关于for循环变量可在for外面使用的的bug修复。

四、关于默认数据类型的重新定义。

五、关于  CFile 类中的 的成员函数变化

ReadHuge  WriteHugevs2010 下的变化更改。

ReadHuge  WriteHuge 改为Read  Write

六、接口参数不匹配

         由于vc和vs中的类型存在数据类型转化的严格程度,vs中要更改其原始的接口类型

         可通过函数转换、强制转换、和更改定义参数类型。

七、Font类的重定义问题

         原因在于vc的系统comdef.h 文件中没有关于Font类的定义。而vs中的comdef.h 文件中有关于Font类的定义,所以会产生重定义的error

       解决方法:将我们自定义的Font 类用命名空间 namespace 进行限定即可,也就是暂时屏蔽系统定义的Font类定义

八、类定义中成员函数因为版本的原因无法识别

前面说道关于版本的问题可以通过修改版本来解决,但是现在遇到的问题就是如果因此类error又去修改版本,会造成和前面的error进行冲突。但是系统的类我们又不能去更改,

解决方法:所以只有去修改项目中的类成员,可以中间加一个映射关系。映射到项目原来所要用到的类成员函数。

九、Cexception为抽象类不能被实例化

原因:VS2003之后的版本中,CException的定义与VC++6.0中不同。还有就是GetErrorMessage调用时出现的问题由于vs中多了参数的定义

解决:用一个CException派生类代替CException。并在GetErrorMessage成员函数的调用时必须加上参数,具体请参照GetErrorMessage的定义。

十、系统文件WinUser中“iPaddedBorderWidth”: 不是“tagNONCLIENTMETRICSA”的成员

原因:NONCLIENTMETRICS has an extra element after VC6 

解决方法:把该语句换成:ncm.cbSize =sizeof(NONCLIENTMETRICS)

十一、关于系统生成关于MFC的函数声明类型不匹配

原因:在于vc 和 vs 的生成MFC代码过程中函数类型的声明不匹配

解决:手动的把项目函数的声明类型更改到可匹配。注意,头文件和实现文件都要更改。

十二、NMHDR和NMTOOLBAR的指针转换问题

原因:接着前一个问题,在修改函数OnToolbarDropDown的参数过程中会牵涉到这两个类型转换的问题。

解决:通过一般的强制转换是不行的,只有通过reinterpret_cast<>来进行转换。


 

链接阶段 error

一、CiniFile中类成员函数的二义性。

原因:在include和根目录中的CiniFile 的两个文件冲突

解决:删除tj_wd/include 中的CiniFile 的两个文件

二、CmemDC类重定义问题

原因:工程中有一个MemDC.h文件,里面定义了一个CMemDC类,不巧的是,VS2010的MFC新增了这个类,所以链接时会出问题。

解决:3 增加一个宏定义,#define CMemDC XCMemDC 将语句加到stdafx.h的最后。(也可以在工程属性页中以编译器指令的形式定义宏,格式为 /D "CMemDC=XCMemDC")。

运行时bug

一、配置文件和库文件的调用路径问题

原因:之前的调用文件的路径有更改

解决:  改成现有文件的路径。

二、关于vector的越界访问

原因:在之前vc6.0平台上对于vector 的越界访问不会产生冲突,而在vs2010及以后的版本中会在运行时出现越界访问的错误

解决:可以利用条件判断将(当vector.size== 0 时)的访问vector元素语句块进行控制。也就是当vector.size != 0时才执行访问操作。

三、关于日期时间的一些数据项无法在控件中显示的问题。

原因:主要是中间的一些time_t类型的变量和在赋值给控件无法转换

解决:将 time_t 类型换成 int 类型,注意:数据类型的结构体不必换成 int,只需要经中间需要显示的 那个  time_t  变量换成 int 类型即可。

四、出现运行时错误时:包括(类型未初始化、参数错误、vector等错误)

原因:大部分都是数据类型引起的或者时在内存拷贝(memcpy)时,字节数不匹配所导致的(会导致越界)。

解决:将数据类型统一或者改变数据类型以适应内存拷贝的大小,不至于越界。

阅读全文
0 0