TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR<一>

来源:互联网 发布:淘宝怎样生成二维码 编辑:程序博客网 时间:2024/05/17 04:19

TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR究竟是神马!!!<一>

许多Windows平台上的 c++猿友常常困惑于一些奇怪的数据类型的定义,如:TCHAR、LPCTSTR...,我在此简单说明下。

一般来说,一个字符能用一个或两个字节来存储。我们称一个字节保存的字符为ANSI字符----所有的英文字符都是这种编码。而称两个字节保存的字符为Unicode,这是包括了世界上所有语言的编码方式。
VC++编译器分别使用char和wchar_t来支持ANSI和Unicode字符集。尽管对Unicode有更具体的定义,但是为了便于理解,假定它是两字节的字符。
(注:Windows不仅仅只使用2字节来表示Unicode字符集,而使用UTF-16字符编码)

如果你想要你的c/c++代码独立于字符集,该如何做呢?
建议:使用通用数据类型和名称来表示字符和字符串。
举个例子:
不要使用
char cResponse;char sUsername[64];
wchar_t cResponse; wchar_t sUsername[64];
为了支持多语种(如:Unicode),你可以把代码写成更通用的方式:
#include<TCHAR.H>TCHAR cResponse;TCHAR sUsername[64];

以下项目General设置页面描述用于编译哪个字符集:(通用- >字符集)



通过这种方式,当你工程被编译成Unicode时,TCHAR就被定义成wchar_t。如果使用ANDI编译,则被翻译成char。你能自由的使用char和wchar_t,工程设置并不会改变其定义。

TCHAR的定义:
#ifdef _UNICODEtypedef wchar_t TCHAR;#elsetypedef char TCHAR;#endif

当你设置“Use Unicode Character Set”时,宏_UNICODE就被定义了,因此TCHAR也就是wchar_t。而当你设置字符集为“Use Multi-Byte Character Set”,那么TCHAR就是char。
同样,为了支持多种字符集和多语言,而使用单一代码库,也要使用特定的函数(宏)。如:使用wcscpy,wcslen,wcscat代替strcpy,strlen,strcat
strlen的定义是:
size_t strlen(const char*);
wcslen定义:
size_t wcslen(const wchar_t* );
你也许会使用_tcslen,其逻辑定义是:
size_t _tcslen(const TCHAR* );

WC是宽字符,因此wcs就是宽字符串。_tcs意味着_T字符串,_T逻辑上是char或者wchar_t。
但是,事实上_tcslen(还有其他_tcs函数)并不是函数,而是宏:
#ifdef _UNICODE#define _tcslen wcslen #else#define _tcslen strlen#endif

你也许会疑惑为什么定义成宏而不是函数,原因很简单:库或DLL可以用相同的名称和原型导出一个函数(不包括C++中的重载)。
举个例子:当你导出一个函数
void _TPrintChar(char);

但是如下情况时:

<span style="font-family: Arial, Helvetica, sans-serif;">void _TPrintChar(wchar_t);</span>
客户端如何来调用?
_TPrintChar函数不能神奇的转换成双字节字符,必须有两个函数的各自定义:

void PrintCharA(char); // A = ANSI void PrintCharW(wchar_t); // W = Wide character
同时包括一个简单的宏来隐藏其区别:
#ifdef _UNICODEvoid _TPrintChar(wchar_t); #else void _TPrintChar(char);#endif

此时客户端就能如下调用:
TCHAR cChar;_TPrintChar(cChar);

注意,TCHAR和_TPrintChar将映射到Unicode或ANSI,因此cChar和函数参数也被映射成char或者wchar_t。

宏的确避免了这些复杂性,允许我们操作字符或者字符串时代替使用ANSI或者Unicode函数。很多使用字符串或者字符的Windows函数都利用宏的便利性,对于程序员来说也更方便,因为只要使用一个函数就够了,例如SetWindowText函数:
// WinUser.H#ifdef UNICODE#define SetWindowText  SetWindowTextW#else#define SetWindowText  SetWindowTextA#endif // !UNICODE

0 0
原创粉丝点击