对于vs2008下MFC的编译或者说vc6到vs2008的移植性问题

来源:互联网 发布:网络信贷业务员好做吗 编辑:程序博客网 时间:2024/05/22 06:55
 

 

对于vs2008下MFC的编译或者说vc6到vs2008的移植性问题

转自(http://hi.baidu.com/popey/blog/item/fbf66e275887890b908f9d21.html)

2009-04-21 23:28
刚刚转入2008下写MFC程序,出了很多问题,小结一下

1.

编译错误:syntax error : identifier '__RPC__in'


同样的程序,换个编译环境就出现如下错误:

syntax error : identifier '__RPC__in'
syntax error : identifier '__RPC__in_opt
syntax error : identifier '__RPC__out_ecount_part'

原因:不同版本的SDK头文件包含有所不同,而以上三个标识符都是定义在头文件"rpcsal.h"中。

解决办法:包含头文件"rpcsal.h"即可

#include <rpcsal.h>

----------------------------------------------------------感谢飘飘白云的文章


2.

关于 #define WINVER

最近在在把一些程序从VC6迁移到VS2008,由此而关注到了Winodws版本的定义问题。

关于版本定义的关键无外乎为程序头文件中对于#define WINVER 和 #define _WIN32_WINNT 的使用,具体为:

#define WINVER 0xXXXX#define _WIN32_WINNT 0xXXXX

该定义一般用于标示程序对运行环境的要求,另外在某些头文件中也有这样的宏定义。如果版本匹配的话就会在编译的时候将这些内容编译,否则就不编译。

定义正确的Windows版本,不仅关系到程序的正确编译,同时也关系到程序的正确运行;在升级的过程中,我就碰到了程序编译正确但运行出错的问题。实例稍候再续。

版本的定义关系到被编译到程序中的内容,这里主要是指系统提供的功能代码。Windows各个版本的功能虽然大差不差,但特定于某个系统功能还是存 在的,于是关系到这些功能的API代码也就有所不一样。当我们在程序中定义了错误的系统版本,被编译进程序的内容便可能包含当前系统不支持的代码片段,这 样的程序即使可能正确编译通过,但在运行的时候,由于在当前系统中找不到相应的内容资源,从而发生错误。这一点熟悉动态链接库(DLL)的人都很清楚,其 实该问题就是和系统动态链接库有关。

Example:
下面为一段获取系统信息提示框的字体信息的代码片段:(编译环境从VC6迁移至VS2008,运行系统为Windows XP)

// Retrieves the message font infoNONCLIENTMETRICS ncm;ncm.cbSize = sizeof(NONCLIENTMETRICS);VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)); // Creates the font according to the message font infom_Font.CreateFontIndirect(&(ncm.lfMessageFont));

程序在VC6下编译运行都正确,迁移至VS2008后,编译正确,但运行时出错。原因是SystemParametersInfo调用失败,这和其传入的参数有关,根本在于 NONCLIENTMETRICS 这个结构体变量的定义。

在新的 Windows SDK 6.0 中,其定义如下:

typedef struct tagNONCLIENTMETRICSA{    UINT    cbSize;    int     iBorderWidth;    int     iScrollWidth;    int     iScrollHeight;    int     iCaptionWidth;    int     iCaptionHeight;    LOGFONTA lfCaptionFont;    int     iSmCaptionWidth;    int     iSmCaptionHeight;    LOGFONTA lfSmCaptionFont;    int     iMenuWidth;    int     iMenuHeight;    LOGFONTA lfMenuFont;    LOGFONTA lfStatusFont;    LOGFONTA lfMessageFont;#if(WINVER >= 0x0600)    int     iPaddedBorderWidth;#endif /* WINVER >= 0x0600 */} #ifdef UNICODE#define NONCLIENTMETRICSW NONCLIENTMETRICS#else#define NONCLIENTMETRICSA NONCLIENTMETRICS#endif

注意最后一个成员的定义条件,其指明了,该成员只能应用于 WINVER >= 0×0600 的系统环境(这里指明了系统为Vista)。
考虑到我迁移程序的时候,是直接利用VS2008将VC6程序转化的方式,然后按VS2008新建项目的StdAfx.h文件内容更新了原来的StdAfx.h头文件,并添加了VS2008项目才有的targerver.h头文件。
根据targetver.h头文件里的下列定义:

#ifndef WINVER                  // 指定要求的最低平台是 Windows Vista。#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。#endif #ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。#endif

我的程序便使用了新的Windows SDK版本的定义。于是编译的时候,NONCLIENTMETRICS 的最后一个成员便编译进了程序,由于系统DLL是动态加载的,所以程序在此可以正确编译。但是在运行的过程中,当前XP系统的DLL不支持该成员(新增的 成员,在该系统下为不可用),这里表现为来自系统API的SystemParametersInfo函数,找不到匹配该系统预定义的 NONCLIENTMETRICS 结构体参数,从而导致程序在运行时出错。

解决方法:
考虑当前系统的版本,添加合适的版本预定义,以程序在当前系统的正确运行。

如上述程序可以在项目的StdAfx.h头文件中添加如下预定义:

#define WINVER 0x0500#define _WIN32_WINNT 0x0500

PS:0×0500 表示Windows 2000,0×0501为Windows XP,0×0502为Windows Server 2003,0×0600 为 Windows Vista。

以上问题并不复杂,主要是对Windows程序中关于版本定义问题的一些了解,以求得在以后的程序中涉及到该类问题,诸如程序移植等等,有一个明确的认识!

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 家里的鼻涕虫泛滥成灾怎么办 菜叶上有蜗牛怎么办 家里面有鼻涕虫怎么办 菜地里的蜗牛怎么办 菜地里有蜗牛怎么办 菜地里有虫子怎么办 心情焦躁多想怎么办 打胎后心情焦躁怎么办 心情不好想发火怎么办 孩子心烦气燥怎么办 心烦气燥睡不着怎么办 心烦心燥睡不着怎么办 小孩心烦气燥怎么办 情绪总是很烦躁怎么办 情绪不好爱生气怎么办 心里每天烦躁该怎么办 心情低落想哭怎么办 心老是烦躁急怎么办 易烦躁睡眠不好怎么办 天气热心情烦躁怎么办 嘴巴里有溃疡怎么办 嘴巴里面反复烂怎么办 多处口腔溃烂怎么办 口腔黏膜破了怎么办 有鼻炎鼻子痒怎么办 感冒就清鼻涕怎么办 怀孕感冒流鼻涕打喷嚏怎么办 过敏性鼻炎打喷嚏流鼻涕怎么办 宝宝黄鼻涕鼻塞怎么办 鼻炎总是打喷嚏流鼻涕怎么办 新生儿流黄鼻涕怎么办 感冒鼻塞流鼻涕喷嚏怎么办 宝宝总是打喷嚏流鼻涕怎么办 不停的打喷嚏流鼻涕怎么办 宝宝不停打喷嚏流鼻涕怎么办 孕妇感冒流鼻涕打喷嚏怎么办 孕妇感冒咳嗽流鼻涕怎么办 鼻子痒流鼻涕流眼泪怎么办 天冷鼻子流鼻涕怎么办 感冒流水样鼻涕怎么办 一直有清水鼻涕怎么办