UNICODE 字符数据的 _T( ) 宏更改

Posted

技术标签:

【中文标题】UNICODE 字符数据的 _T( ) 宏更改【英文标题】:_T( ) macro changes for UNICODE character data 【发布时间】:2011-05-07 04:44:02 【问题描述】:

我有 UNICODE 应用程序,其中我们使用定义如下的 _T(x)。

#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif

我知道 L 被定义为 wchar_t,在任何平台上都是 4 个字节。如果我错了,请纠正我。我的要求是我需要 L 为 2 个字节。因此,作为编译器破解,我开始使用 -fshort-wchar gcc 标志。但是现在我需要将我的应用程序移到 zSeries 上,在该平台上我看不到 -fshort-wchar 标志的效果。

为了让我能够将我的应用程序移植到 zSeries 上,我需要修改 _T( ) 宏,即使在使用 L ##x 并且不使用 -fshort-wchar 标志之后,我也需要得到2 字节宽的字符数据。有人可以告诉我如何更改 L 的定义,以便在我的应用程序中始终将 L 定义为 2 字节。

【问题讨论】:

AFAIK,wchar_t 在 Windows 上是 2 字节宽,所以 wchar_t 的大小取决于实现。 wchar_t 通常用作WCHAR 的基本类型,它肯定是2 个字节宽。像MessageBoxW 这样的函数有WCHAR* 参数,所以WCHARwchar_t 相同使得Windows 编程更容易。 L 只是字符“L”。它没有被定义为任何东西。在 C++ 中,L"hello world" 只定义了一个宽字符串文字。但是 L 不会被任何东西取代。 【参考方案1】:

你不能 - 没有 c++0x 支持。 c++0x 定义了以下声明字符串字面量的方式:

“某些实现定义的编码中的 char 字符串” - char u8"utf8 字符字符串" - char u"string of utf16 chars" - char16_t U"string of utf32 chars" - char32_t L"wchar_t 的字符串在某些实现定义的编码中" - wchar_t

在 c++0x 被广泛支持之前,以跨平台方式编码 utf-16 字符串的唯一方法是将其分解为位:

// make a char16_t type to stand in until msvc/gcc/etc supports
// c++0x utf string literals
#ifndef CHAR16_T_DEFINED
#define CHAR16_T_DEFINED
typedef unsigned short char16_t;
#endif

const char16_t strABC[] =  'a', 'b', 'c', '\0' ;
// the same declaration would work for a type that changes from 8 to 16 bits:

#ifdef _UNICODE
typedef char16_t TCHAR;
#else
typedef char TCHAR;
#endif
const TCHAR strABC2[] =  'a', 'b', 'b', '\0' ;

_T 宏只能在 wchar_t 为 16 位宽的平台上交付货物。而且,替代方案仍然不是真正的跨平台:char 和 wchar_t 的编码是实现定义的,因此“a”不一定为“a”(0x61)编码 unicode 代码点。因此,严格来说,这是编写字符串的唯一方法:

const TCHAR strABC[] =  '\x61', '\x62', '\x63', '\0' ;

这太可怕了。

【讨论】:

请注意,在 IBM zSeries 上 a 仍然等于 0x61,但 j 不是 0x6a【参考方案2】:

啊!便携的奇迹:-)

如果您有适用于所有平台的 C99 编译器,请使用来自 <stdint.h>int_least16_tuint_least16_t、...。大多数平台也定义了int16_t,但它不是必须存在的(如果平台能够一次恰好使用 16 位,则必须定义 typedef int16_t)。

现在将所有字符串包装在 uint_least16_t 的数组中,并确保您的代码不期望 uint_least16_t 的值在 65535 处包装...

【讨论】:

不能解决问题 - 你仍然没有办法创建 const uint_least16_t[] 文字。 我正在使用 GCC 编译器。除了 -fshort-wchar 是否有任何其他 GCC 编译器标志来更改 wchar_t 的大小。 @MSalters: const uint_least16_t data[] = 'f', 'o', 'o', 'b', 'a', 'r', '\0' ; 您是否发现了问题的“我需要修改_T( ) 宏”部分? _T("foobar") 是如何扩展为 const uint_least16_t data[] = 'f', 'o', 'o', 'b', 'a', 'r', '\0' ; 的? 你想要两件不相容的事情:至少其中一件事情必须妥协——电脑比你顽固得多

以上是关于UNICODE 字符数据的 _T( ) 宏更改的主要内容,如果未能解决你的问题,请参考以下文章

Unicode _T和L和_TXET

VC++中L和_T是啥?

关于 char wchar_t TCHAR _T() ||| 宏 _T TEXT _TEXT L

CString构造函数

怎么转化为LPCWSTR

Windows Unicode相关