C/C++关于版本兼容的方法.txt

来源:互联网 发布:分布式视频矩阵 编辑:程序博客网 时间:2024/06/04 18:03

引言
编程多了,常常有些感触.笔者发现在windows下很多结构都有一个dwSize来表示这个结构多大,实际上这个成员是用来进行版本兼容的.
最典型的一个结构就是OPENFILENAME.这个结构用在了打开文件对话框.里面的第一个成员lStructSize就是用来存放结构的大小.使用在不同的环璄下
_WIN32_WINNT > 0x0500 时和不定义这个宏sizeof(OPENFILENAME)会不一样的那么lStructSize就会不一样,这样windows内部根据这个成员来得知程序运行的版本.
所显示出的对话框就会不相同.这些都是大家共知的啦,笔者谈了这些只是想引入一个话题:我们如何来进行代码的兼容性.
正题
我们先来看如下的一个例子.
a.h
typedef struct tagOPTION
{
   DWORD dwSize;
   DWORD AAA;
   DWORD BBB;  
   DWORD CCC;
}OPTION;

比如这是我定义的一个结构可以进行一些功能的设置.
通过一个结构的指针传给我写的一个引出函数 HRESULT SetOption(OPTION *);
我在代码里判断结构大小如果大小==sizeof(OPTION)则进行操作,否则返回一个错误代码.
在代码用了一些时间后我们需要对这个结构进行扩充,但要求对以前的这个版本兼容.由于这个头文件是给了别的开发者用的.兼容性要考虑到那些开发者生成的可执行代码是可以在新的平台上运行的.
这时我的dwSize就发挥了强大的作用,我只需要判断一下dwSize是不是旧版本的大小,如果是则调用原来的那份代码就可以了.

我的头文件马上变成了

typedef struct tagOPTION
{
   DWORD dwSize;
   DWORD AAA;
   DWORD BBB;
   DWORD CCC;
#ifdef MYSYSTEMVER >= 2
   DWORD DDD;
#endif 
}OPTION;
把旧的SetOption改为SetOption_V1()
新开了一个函数SetOption调用方式相同
HRESUT SetOptiton(OPTION * opt)
{
    if(opt->dwSize == 12)
        return SetOption_V1(opt)
    if(opt->dwSize == sizeof(OPTION))  
.....

}
难道我们一定要在代码中留下MagicNumber吗?
所以再改

#define SIZE_OPTION_V1 12
HRESUT SetOptiton(OPTION * opt)
{
    if(opt->dwSize == SIZE_OPTION_V1 )
        return SetOption_V1(opt)
    if(opt->dwSize == sizeof(OPTION))  
.....

}

代码现在不错了,但是笔者认为代码现在还不理想.因为手动算大小很容易把结构算错.
如果结构成员多了,我们如何来计算呢?,还有SetOption_V1里的代码还有一个sizeof(OPTION)也要改一下
不然原来的代码可不能运行得了.
但是#define OPTION_V1 sizeof(OPTION)会总是新版本的大小.
又想用sizeof()来自动计算结构的大小.
天无绝人之路我还是想到了方法
比如旧版文件采用如下方法编写

typedef struct tagOPTION_CORE
{
   DWORD dwSize;
   DWORD AAA;
   DWORD BBB;  
   DWORD CCC;
}OPTION_CORE;

typedef OPTION_CORE OPTION_V1;
typedef OPTION_CORE tagOPTION_V1;
const SIZE_OPTION_V1  = sizeof(OPTION_V1);
#define OPTION OPTION_V1
如果需要升级则新加如下代码

struct tagOPTIONV2:public OPTION_CORE
{
   DWORD DDD;
};
typedef tagOPTIONV2 OPTIONV2;
const SIZE_OPTION_V2 = sizeof(OPTIONV2)

#undef  OPTION
#define OPTION tagOPTIONV2
#endif

现在我的代码就变成了


HRESUT SetOptiton(OPTION * opt)
{
    if(opt->dwSize == SIZE_OPTION_V1 )
        return SetOption_V1(opt)
    if(opt->dwSize == SIZE_OPTION_V2)  
.....

}


如果还需要升级只需要按以上的代码再新加一个结构.
并且使用者永远只需要使用OPTION结构,并且sizeof(OPTION)总等于他拿到的头文件的版本中结构的大小.

原创粉丝点击