_T( ) 宏对 UNICODE 字符数据进行更改

发布于 2024-10-01 07:36:07 字数 454 浏览 2 评论 0原文

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

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

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

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

I have UNICODE application where in we use _T(x) which is defined as follows.

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

I understand that L gets defined to wchar_t, which will be 4 bytes on any platform. Please correct me if I am wrong. My requirement is that I need L to be 2 bytes. So as compiler hack I started using -fshort-wchar gcc flag. But now I need my application to be moved to zSeries where I don't get to see the effect of -fshort-wchar flag in that platform.

In order for me to be able to port my application on zSeries, I need to modify _T( ) macro in such a way that even after using L ##x and without using -fshort-wchar flag, I need to get 2byte wide character data.Can some one tell me how I can change the definition of L so that I can define L to be 2 bytes always in my application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

£噩梦荏苒 2024-10-08 07:36:07

如果没有 c++0x 支持,你就不能。 c++0x 定义了以下声明字符串文字的方法:

  • “某些实现定义的编码中的 char 字符字符串” - char
  • u8“utf8 字符字符串” - char
  • u“utf16 字符字符串” - char16_t
  • U“utf32 字符字符串" - 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' };

这太可怕了。

You can't - not without c++0x support. c++0x defines the following ways of declaring string literals:

  • "string of char characters in some implementation defined encoding" - char
  • u8"String of utf8 chars" - char
  • u"string of utf16 chars" - char16_t
  • U"string of utf32 chars" - char32_t
  • L"string of wchar_t in some implementation defined encoding" - wchar_t

Until c++0x is widely supported, the only way to encode a utf-16 string in a cross platform way is to break it up into bits:

// 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' };

The _T macro can only deliver the goods on platforms where wchar_t's are 16bits wide. And, the alternative is still not truly cross-platform: The coding of char and wchar_t is implementation defined so 'a' does not necessarily encode the unicode codepoint for 'a' (0x61). Thus, to be strictly accurate, this is the only way of writing the string:

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

Which is just horrible.

沐歌 2024-10-08 07:36:07

啊!可移植性的奇迹 :-)

如果您有适用于所有平台的 C99 编译器,请使用 中的 int_least16_tuint_least16_t、...。大多数平台也定义了 int16_t,但它不需要存在(如果平台能够一次使用 16 位,则必须定义 typedef int16_t)。

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

Ah! The wonders of portability :-)

If you have a C99 compiler for all your platforms, use int_least16_t, uint_least16_t, ... from <stdint.h>. Most platforms also define int16_t but it's not required to exist (if the platform is capable of using exactly 16 bits at a time, the typedef int16_t must be defined).

Now wrap all the strings in arrays of uint_least16_t and make sure your code does not expect values of uint_least16_t to wrap at 65535 ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文