使Win32应用程序在ANSI& UNICODE

时间:2011-06-25 04:27:42

标签: c++ winapi encoding

我想让我的Win32 C ++应用程序能够在任何编码版本(UNICODE& ANSI)上播放。现在我对两个(或更多?)编码之间究竟有什么区别感到困惑?

为了使我的Win32应用程序交叉编码兼容,这意味着我必须通过我的代码&用std :: wstring替换每个std :: string,然后用wchar_t *替换每个char ,然后用L“”替换每个文字字符串(“”)?

如果我的应用程序在UNICODE计算机上运行会发生什么?我的应用程序中有一个std :: string吗?

对于我的应用程序交叉编码兼容所需的步骤,您有什么建议吗? 例如: - 更改所有c_strings&字符串到他们的UNICODE等价物 - 将任何Win32函数更改为uncide版本(例如,从getenv()更改为_wgetenv())

4 个答案:

答案 0 :(得分:6)

如果我的应用程序在UNICODE计算机上运行会发生什么?我的应用程序中有一个std :: string?

计算机不是ANSIUnicode,而是运行计算机的操作系统。不支持Unicode的Windows的最后一个版本是Windows 3.11 for Workgroups。如果在UniCode上运行ASCII编译的应用程序。

两种(或更多?)编码之间究竟有什么区别?

什么是ASCII?
ASCII是一种七位编码技术,它为美国英语中最常使用的128个字符中的每个字符分配一个数字。这允许大多数计算机记录和显示基本文本。 ASCII不包括其他国家/地区经常使用的符号。

什么是Unicode?
回归ASCII的一个主要原因是你只能有256个不同的字符。但是,日语和阿拉伯语等语言有数千个字符。因此ASCII在这些情况下不起作用。结果是Unicode允许最多65,536个不同的字符。

Unicode是ISO和Unicode Consortium尝试开发电子文本的编码系统,其中包括现有的每个书面字母。 Unicode使用8位,16位或32位字符,具体取决于具体的表示形式,因此Unicode文档通常需要的磁盘空间最多为ASCII或Latin-1文档的两倍。 Unicode的前256个字符与Latin-1相同。

在Win32中,#define -ing UNICODE_UNICODE宏支持UNICODE。反过来,这会导致程序使用Win32函数的Unicode变体。

对于我的应用程序交叉编码兼容所需采取的步骤,您有什么建议吗?

每个Win32函数(接受或返回一个字符串)有两个变体,一个用于ASCII,另一个用于Unicode。函数调用解析为其中之一,具体取决于是否定义了UNICODE宏。因此,您应该定义宏并开始使用Unicode版本的函数。例如:

std::string替换每个std::wstring
char替换每个wchar_t*string("")替换每个文字L"" 在Windows等中使用TCHAR支持

正如您所指出的那样,您需要注意的事项列表,请注意,这不是完整列表。

基本上,您必须在代码中使用类型和函数调用的所有Unicode版本。

答案 1 :(得分:3)

Windows内部未使用Unicode的最新版本是Windows ME。对新代码的建议是仅使用Unicode。当您需要读取和写入使用特定代码页编码的文件时,可能需要进行一些转换。

您的初步想法是正确的。如果您正在使用Microsoft的CString,它有两个版本CStringA和CStringW - 您需要更改一个编译器定义,它将在您指定CString的每个位置使用CStringW,一切都会正常工作。您应该使用std :: wstring而不是std :: string。使用L""为每个字符串文字加前缀,或使用Microsoft的宏_T(""),它将转换为相同的内容。

答案 2 :(得分:3)

编译ANSI或Unicode的程序时,你会影响两件事。

  1. 调用哪组API。假设您的代码调用CreateFile()。调用的实际API是CreateFileA()CreateFileW()(ANSI或Wide(即Unicode)),具体取决于您的编译器设置。在内部,NT核心使用Unicde进行所有API。 ANSI API只是将其字符串参数转换为ANSI并调用Unicode API。许多API仅限Unicode。
  2. 如何扩展T*个宏。 {}将最终在ANSI模式下扩展为TCHAR,在Unicode模式下扩展为char
  3. wchar_tstd::string之类的内容在您需要调用API并希望将字符串传递给它们之前不会受到影响。 std::wstringstring的使用应由您的程序需求决定,而不是由ANSI或Unicode编译。

    您可以根据需要使用ATL轻松转换字符串。

    wstring

    或者,如果您愿意,可以使用// assume compiled for Unicode #include <atlbase.h> void myfunc() { USES_CONVERSION; std::string filename = "..."; HANDLE hFile = CreateFile(A2W(filename.c_str()), ... ,无论代码是针对ANSI还是Unicode编译,您的代码都将正常工作。

答案 3 :(得分:-1)

您可以在案例中使用TCHAR。

在UNICODE中,TCHAR是WCHAR。 在非UNICODE中,TCHAR是CHAR。

如果你想使用std :: string,我建议你使用以下用途。

 #ifdef UNICODE
 #define std::tstring str::wstring
 #else
 #define std::tstring str::string
 #endif

在程序中使用std :: tstring。