我想让我的Win32 C ++应用程序能够在任何编码版本(UNICODE& ANSI)上播放。现在我对两个(或更多?)编码之间究竟有什么区别感到困惑?
为了使我的Win32应用程序交叉编码兼容,这意味着我必须通过我的代码&用std :: wstring替换每个std :: string,然后用wchar_t *替换每个char ,然后用L“”替换每个文字字符串(“”)?
如果我的应用程序在UNICODE计算机上运行会发生什么?我的应用程序中有一个std :: string吗?
对于我的应用程序交叉编码兼容所需的步骤,您有什么建议吗? 例如: - 更改所有c_strings&字符串到他们的UNICODE等价物 - 将任何Win32函数更改为uncide版本(例如,从getenv()更改为_wgetenv())
答案 0 :(得分:6)
如果我的应用程序在UNICODE计算机上运行会发生什么?我的应用程序中有一个std :: string?
计算机不是ANSI
或Unicode
,而是运行计算机的操作系统。不支持Unicode的Windows的最后一个版本是Windows 3.11 for Workgroups。如果在UniCode上运行ASCII编译的应用程序。
两种(或更多?)编码之间究竟有什么区别?
什么是ASCII?
ASCII是一种七位编码技术,它为美国英语中最常使用的128个字符中的每个字符分配一个数字。这允许大多数计算机记录和显示基本文本。 ASCII不包括其他国家/地区经常使用的符号。
什么是Unicode? strong>
回归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的程序时,你会影响两件事。
CreateFile()
。调用的实际API是CreateFileA()
或CreateFileW()
(ANSI或Wide(即Unicode)),具体取决于您的编译器设置。在内部,NT核心使用Unicde进行所有API。 ANSI API只是将其字符串参数转换为ANSI并调用Unicode API。许多API仅限Unicode。T*
个宏。 {}将最终在ANSI模式下扩展为TCHAR
,在Unicode模式下扩展为char
。 wchar_t
和std::string
之类的内容在您需要调用API并希望将字符串传递给它们之前不会受到影响。 std::wstring
与string
的使用应由您的程序需求决定,而不是由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。