确定将宽字符与不兼容的字符 API 一起使用时的最佳做法



好吧,所以我最近又重新研究了C++。我已经13年没有研究过任何C++代码了。

我正在为Windows设计一款软件,我正在努力实现严格为UTF-8的第三方代码(如libssh2),并且不提供其他宽字符API实现。回到Windows,我看到的每个API都使用UTF-16(wchar_t)。

所以我的问题是:每次使用非标准的Windows实现(例如libssh2)时,我是否被迫进行字符串转换?我有一个作为wchar返回的变量,但libssh2neneneba API只提供了一个char实现。

我应该坚持使用char而不是wchar_t吗?如果我这样做,那么我将再次被迫转换为wchar_t以使用Windows API。我在代码中使用了几个第三方源代码和几个Windows API。我的头很疼。

这里的最佳做法是什么?

您最好的选择是使用您最常在任何地方使用的编码,并在每个其他端点进行转换。在这种情况下,听起来你想在任何地方使用UTF-8字符串,并在每个Windows API调用点(或一组调用,如果它们是连续的)转换为UTF-16并返回,因为听起来你的外部调用比Windows API调用多得多。这应该有望限制您实际必须进行的转换数量,并且应该表现得相当好。如果您发现像这样的转换太慢,请使用仪器来确定,然后看看是否有其他API可以用于转换(请参阅Raymond Chen的"Loading the dictionary"子系列,以更好地了解后者,但请记住Knuth关于过早优化的格言)。

这里的最佳实践是什么?

你已经知道答案了。如果API需要具有特定编码的字符串,则必须提供具有该字符编码的字符串。

如果您正在处理多个API,这些API期望使用不同字符编码的字符串,则必须在编码之间进行转换。

Windows始终使用UTF-16(只有极少数例外)。要在UTF-8和UTF-16之间转换,需要分别调用MultiByteToWideChar和WideCharToMultiByte。


如果您需要决定在应用程序中使用什么"本机"字符编码,您可以使用以下列表来做出明智的决定:

  • 频率:应用程序调用使用一种或另一种编码的函数的频率。选择应用程序经常使用的字符编码
  • 模式:您的应用程序是否主要公开使用相同字符编码将字符数据传递给多个API函数的模式?如果是这样,那么字符编码就是一个很好的候选者
  • 数据完整性:Unicode的一个特点是,某些抽象字符可以用不同的代码单元序列进行编码。如果需要在调用之间保留精确的代码单元序列,则使用该字符编码是一个安全的选择
  • 安全性:charwchar_t(在Windows上)之间的一个核心区别是,wchar_t明确指定UTF-16LE编码的字符,而char可以是ASCII、ANSI、UTF-8或其他编码。如果没有其他因素产生决定,那么在Windows上使用wchar_t/UTF-16可以提供额外的安全性。当(可能)将非Unicode字符串传递给预期wchar_t/UTF-16的API时,它允许编译器报告错误

最新更新