2010-11-09 34 views
5

Tôi có ứng dụng UNICODE trong đó chúng tôi sử dụng _T (x) được định nghĩa như sau._T() thay đổi vĩ mô cho dữ liệu ký tự UNICODE

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

Tôi hiểu rằng L được xác định là wchar_t, sẽ là 4 byte trên nền tảng bất kỳ. Hãy sửa tôi nếu tôi sai. Yêu cầu của tôi là tôi cần L là 2 byte. Vì vậy, như trình biên dịch hack tôi bắt đầu sử dụng cờ-gshort-wchar gcc. Nhưng bây giờ tôi cần ứng dụng của tôi để được chuyển đến zSeries, nơi tôi không nhận thấy hiệu ứng của cờ -fshort-wchar trong nền tảng đó.

Để tôi có thể chuyển ứng dụng của mình trên zSeries, tôi cần sửa đổi macro _T() theo cách mà ngay cả sau khi sử dụng L ## x và không sử dụng cờ -fshort-wchar, tôi cần nhận được 2byte dữ liệu ký tự rộng.Có thể một số cho tôi biết làm thế nào tôi có thể thay đổi định nghĩa của L để tôi có thể định nghĩa L là 2 byte luôn trong ứng dụng của tôi.

+3

AFAIK, wchar_t là 2bytes rộng trên Windows, vì vậy kích thước của wchar_t là thực hiện phụ thuộc. – nothrow

+1

'wchar_t' thường được sử dụng làm kiểu cơ sở cho' WCHAR', chắc chắn là 2 byte rộng. Các hàm như 'MessageBoxW' có các đối số' WCHAR * ', vì vậy việc có' WCHAR' và 'wchar_t' giống hệt nhau làm cho việc lập trình Windows trở nên dễ dàng hơn nhiều. – MSalters

+0

L chỉ là ký tự 'L'. Nó không được định nghĩa là bất cứ điều gì. Trong C++, L "hello world" chỉ định nghĩa một chuỗi * rộng *. Nhưng L không bị thay thế bởi bất cứ thứ gì. – jalf

Trả lời

5

Bạn không thể - không hỗ trợ C++ 0x. C++ 0x xác định những cách sau đây để bày tỏ ý xâu:

  • "chuỗi ký tự char trong một số thực hiện được xác định mã hóa" - char
  • u8 "Chuỗi các ký tự utf8" - char
  • u "chuỗi của chars UTF16" - char16_t
  • U "chuỗi ký tự utf32" - char32_t
  • L "chuỗi wchar_t trong một số thực hiện được xác định mã hóa" - wchar_t

Cho đến C++ 0x được hỗ trợ rộng rãi, cách duy nhất để mã hóa một chuỗi utf-16 trong một nền tảng cách chéo là để phá vỡ nó thành bit:

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

vĩ mô _T chỉ có thể cung cấp hàng hoá trên nền tảng nơi wchar_t's rộng 16bits. Và, sự thay thế vẫn không thực sự đa nền tảng: Việc mã hóa char và wchar_t được thực hiện được định nghĩa sao cho 'a' không nhất thiết mã hóa codepoint unicode cho 'a' (0x61). Do đó, để chính xác hơn, đây là cách duy nhất để viết chuỗi:

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

Điều này thật khủng khiếp.

+0

Hãy nhớ rằng, trên một zSeries của IBM 'a' vẫn bằng 0x61', nhưng' j' không phải là '0x6a'. – MSalters

0

Ah! Những điều kỳ diệu về tính di động :-)

Nếu bạn có trình biên dịch C99 cho tất cả nền tảng của mình, hãy sử dụng int_least16_t, uint_least16_t, ... từ <stdint.h>. Hầu hết các nền tảng cũng định nghĩa int16_t nhưng không bắt buộc phải tồn tại (nếu nền tảng có khả năng sử dụng chính xác 16 bit tại một thời điểm, typedef int16_t phải được xác định).

Bây giờ quấn tất cả các chuỗi trong mảng của uint_least16_t và chắc chắn rằng mã của bạn không mong đợi giá trị của uint_least16_t quấn tại 65535 ...

+0

Không giải quyết được sự cố - bạn vẫn không có cách tạo 'const uint_least16_t []' literals. – MSalters

+1

Tôi đang sử dụng trình biên dịch GCC. Có lá cờ trình biên dịch GCC khác hơn -fshort-wchar để thay đổi kích thước của wchar_t. –

+0

@MSalters: 'const uint_least16_t dữ liệu [] = {'f', 'o', 'o', 'b', 'a', 'r', '\ 0'}; ' – pmg

Các vấn đề liên quan