在Unicode应用程序中使用ANSI函数有什么限制吗?

Are there any limitations from using ANSI Functions in a Unicode Application

本文关键字:什么 函数 ANSI 应用程序 Unicode      更新时间:2023-10-16

我有一个严格使用Unicode函数和数据类型的c++本地WinAPI应用程序。例如,CreateWindowW(), SendMessageW(), wstring, WCHAR等。现在我打算扩展我的应用程序,使用SQLite3。

我的问题: SQLite3库是ANSI。这意味着我必须使用char*作为大多数函数参数。

在Unicode应用程序中使用ANSI函数是否有任何限制或负面影响?

如果有的话,这些影响可能是什么?

SQLite不局限于ANSI。认为char*意味着ANSI编码文本是一种误解。并非所有操作char*数据的函数都假定数据是ANSI编码的。在SQLite的情况下,它完全支持Unicode,并使用使用UTF-8编码的char*数据。

如果你打算继续在你的应用程序内部使用UTF-16编码的文本,你需要在你的代码和SQLite代码之间的边界添加一个适配器层。向SQLite传递数据时将UTF-16转换为UTF-8,接收数据时将UTF-16转换为UTF-8。

在我看来,这使得你问的问题有点没有意义,但我还是要解决这个问题:

在Unicode应用程序中使用ANSI函数是否有任何限制或负面影响?

使用ANSI函数最明显的缺点是:

  1. 严重限制的字符集。
  2. 在不同字符集之间转换的性能成本。
  3. 由于在单个代码库中使用多个字符集而导致程序员混淆和错误的风险。

没有限制,您可以在Unicode应用程序中使用ANSI字符串。

一些细节:Unicode应用程序是编译时定义的。在运行时,程序可以同时使用Unicode和ANSI字符串。

例如:

char* ptr1;     // this is always ANSI string
wchar_t* ptr2;  // this is always Unicode string
TCHAR* ptr3;    // this is generic string, which is compiled as char* or wchar_t*

Unicode/ANSI配置通过解释通用文本宏(如TCHAR)而有所不同。一些Windows API也使用通用文本宏来实现。例如:SetWindowText实际上是宏,在ANSI配置中扩展为SetWindowTextA,在Unicode配置中扩展为SetWindowTextW

任何非通用字符串或API名称(如char*, SetWindowTextW等)在任何程序配置中都以相同的方式工作。

使用ATL转换宏在不同(泛型和非泛型)字符串类型之间进行转换:http://msdn.microsoft.com/en-us/library/87zae4a3%28v=vs.80%29.aspx

您可以在Unicode应用程序中使用基于ansi的api。只需在将输入的Unicode字符串传递给API时将其转换为Ansi,并在从API返回时将任何输出的Ansi字符串转换为Unicode。您可以使用WideCharToMultiByte()MultiByteToWideChar(),或者更高级的包装器,如CString、ATL转换等。