极光炫影 » 日志 » 关于Unicode
关于Unicode
极光炫影 发表于 2007-04-23 16:51:00
很早想写这篇文章了,不过一直懒得写,今天补上:-)
现在写软件一般都写成Unicode版,这样只要开发一个母板,然后更换一下资源就可以很方便地进行多国语言的移植。
Windows提供了对Unicode很好的支持,大家知道一般API函数都有******A和******W两套,例如CreateWindow就有CreateWindowA和CreateWindowW两个版本。当然一般大家在开发期间是不会调用CreateWindowA或者CreateWindowW,而是调用“CreateWindow”。其实将“CreateWindow”翻译成“CreateWindowA”或者“CreateWindowW”是由编译器完成的。你可以找任何一个PE文件浏览器看看,没有一个Win32程序导入的API中有叫“CreateWindow”的,为什么?答案很简单,因为根本没有“CreateWindow”这个函数。编译器根据是否定义了UNICODE宏来“翻译”API:如果定义了就调用******W版本的API,如果没有定义就调用******A版本的API。但是所有的API都有A和W版本吗?答案是否定的。为什么?答案也很简单,自己想去吧,呵呵。
Windows内部是如何处理这两个版本的API的呢?不会是分别傻傻地都实现一遍吧?答案又是否定的。其实Windows 2000以后的Windows内核是基于Unicode的。在这些Windows系统上,A版本的API其实是一个转换函数,其作用只是将参数做必要的转换,然后调用W版的API。所以说,W版的API效率其实比A版的高。但是在Windows98等系统上,情况却正好相反。
我现在写的程序除了那些实验性质的小程序外,基本上都是用通用字符版本的。这个又是什么?其实就是使用TCHAR类型。其定义如下:
#ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
#endif
可见TCHAR在UNICODE宏被定义时被解释为WCHAR,否则解释为char。这样只要改一个地方就可以改全局,岂不乐哉?且慢!发现没有,原来你习惯使用的类似strcpy之类的函数在定义了UNICODE后不能操作TCHAR字符串了。怎么解决呢?简单方法有两个:其一是用lstrcpy之类的函数代替,它们是API,至于效率吗,呵呵,不敢恭维;其二是定义_UNICODE(这个宏用于CRT,请区别于UNICODE宏),给原来“赤裸”的字符串套上“_T”这件衣服,然后将strcpy用_tcscpy之类的函数代替,他们也是CRT函数,效率比较高。选哪个,自己决定吧。
但是问题还不止于此,你可能会发现用_ftprintf之类函数向文件中写中文的时候,会出现很大问题,当然,人品好+运气好的话,可能会没有问题:-)怎么解决?其实很简单的,但是这里就不说了。不过,让fstream之类的C++类对TCHAR也不感冒那可能稍微麻烦一点,不过实现还是没有问题的。至于MFC,其对TCHAR的支持相当傻瓜,很多自动会调用相应版本的函数的,直接用好了。
- » 城市商业银行的前生今世
- » 我的长安
- » It's a "Hello world"
- » 读书还是工作?
