在Unicode应用程序中使用ANSI函数有什么限制吗?
Are there any limitations from using ANSI Functions in a Unicode Application
我有一个严格使用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函数最明显的缺点是:
- 严重限制的字符集。
- 在不同字符集之间转换的性能成本。
- 由于在单个代码库中使用多个字符集而导致程序员混淆和错误的风险。
没有限制,您可以在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转换等。
- 什么时候调用组成单元对象的析构函数
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 什么时候调用析构函数
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 是什么让放置新调用对象的构造函数?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 在C 中,对2D数组的增量是什么?函数断言(0)做什么?
- 我应该使用什么函数签名来返回对可能不存在的对象的引用
- 一个类的构造函数,为另一个类进行强制转换.将调用什么函数
- 在 opencv for c 中,什么函数与 Mat::convertTo 和 cvtColor() 完全相同
- 当按下Alt-Enter键时调用什么函数
- C库导出什么函数?
- 使用什么函数来选择文本
- c++在空类中编写和调用什么函数?
- 在共享库的构造函数(_init部分)中,如何知道什么函数被中断了?
- 我可以用什么函数来获取按钮的把手