woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

VC 程序员的阵痛--将多字节环境移植到Unicode环境

环境的移植是什么样的感受?我的一位师哥说的很真切:这是一项体力活!说的一点没错。在我将项目的环境设置成Unicode,编译时竟出现500多了错误!而在多字节环境下却可以正常运行。在MSDN、网上查找了相关移植的资料.发现所谓的移植主要是将一些多字节函数使用Unicode环境下的函数替换一下.

 

例如strcmp()函数原型为:

 

未设置任何环境下的函数

int strcmp(

   const char *string1,

   const char *string2

);

 

Unicode环境下的函数

int wcscmp(

   const wchar_t *string1,

   const wchar_t *string2

);

 

多字节环境下的函数

int _mbscmp(

   const unsigned char *string1,

   const unsigned char *string2

);

 

因此,我按照MSDN上的函数说明,使用查找替换的方法,将所有strcmp 替换为 wcscmp.重新编译一下,结果错误不仅没有减少,反而又多了起来.经过查看错误列表,发现新增的一些错误来自些带多字节参数的函数, void Compress(const char *lpszInfile,const char *lpszOutfile).由于这些函数参数形式为多字节的,而在函数体内部却使用Unicode环境下的比较函数,这当然是行不通的.再次查看MSDN,发现如下表格:

Generic-Text Routine Mappings

TCHAR.H routine

_UNICODE & _MBCS not defined

_MBCS defined

_UNICODE defined

_tcscmp

strcmp

_mbscmp

wcscmp

它的意思是说你可以使用宏定义函数来代替MBSCUnicode函数. Routine:说明该宏定义函数只有在运行时才会动态的根据环境来决定使用MBSC函数还是Unicode函数.

现在我们分别在UnicodeMBSCUnKnow环境下查看_tcscmp函数的提示信息:

Unicode环境

clip_image001

 

MBSC环境

clip_image002

 

UnKnow环境

clip_image003

一切都很明白。宏函数在各种环境下使用了不同的函数定义。现在我们可以放心的使用宏函数来替换原来的函数了。

于是我将需要的替换的函数都用宏函数做了替换。但是错误仍然很多,到底什么地方出错了?我又仔细的查看了错误信息。原来许多类的函数带有char类型参数,由于在Unicode环境下使用宏函数,所以函数的参数被解释成了Unicode下的变量类型wchar_t,所以产生了类型不匹配的错误.但是我总不能都将所有的char类型都替换成wchar_t类型吧。这样一来,就只能在Unicode环境下编译使用了,如果需要转换为MBCS环境又要修改变量类型,所以不具备通用性。经过思考,我决定采用两种方法来解决此问题。

一是保留原有参数类型,在函数体内不使用宏函数,如果参数是MBCS类型的就使用MBSC类型的函数。如果使用Unicode参数类型就使用Unicode类型函数。

如:参数是const char* 就使用 strcpy,strcmp之类的函数。

    参数是 const wchar_t* 就使用 wcscpy,wcscmp之类的函数。

二是使用宏变量类型TCHAR,该变量也会根据环境的不同,使用不同的变量类型。

如:MBSC环境下,TCHAR 代表char

    Unicode环境下,TCHAR代表 wchar_t

    经过如上的反复修改和调试,错误终于改完了。谢天谢地!

    可惜,我高兴的太早了。许多隐藏的错误弄得我焦头烂额。在填充一个树状控件时,每一个树项都成了乱码。但编译、运行为什么没有出错?带着这个疑问,我使用调试器查看了运行时的变量值。结果发现,从文件中读取的树项被放入了char类型的缓冲区,而填充树项却在Unicode环境下进行的。我们知道:在MBSC环境下A=0x41,而在Unicode环境下A=0x41 00,所以多字节的字符串AB=0x4142,而在Unicdoe环境下则变成了AB=0x14 00 42 00,所以在Unicode环境下,0x4142被认为是一个字符,但编码中并不存在这一字符,结果就变成了乱字符串。原因找到了,解决的办法就是使用MultiByteToWideCharWideCharToMultiByte两个函数在MBCSUnicode环境下来回的转换。现在好了,终于完成了环境的移植。心里踏实多了。

    希望我的这篇文章能对大家有所帮助。

 

posted on 2009-07-28 11:17 肥仔 阅读(2028) 评论(1)  编辑 收藏 引用 所属分类: VC 存档

评论

# re: VC 程序员的阵痛--将多字节环境移植到Unicode环境  回复  更多评论   

楼主这个项目应该是没有使用到第三方库,当你使用好几十第三方库时,你就知道有多痛苦了。。。
2010-04-30 15:49 | zenghp

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