【问题标题】:WinAPI Unicode and ANSI functionsWinAPI Unicode 和 ANSI 函数
【发布时间】:2015-11-14 23:22:47
【问题描述】:

大部分 WinAPI 调用都有UnicodeANSI 函数调用

例如:

function MessageBoxA(hWnd: HWND; lpText, lpCaption: LPCSTR; uType: UINT): Integer; stdcall;external user32;

function MessageBoxW(hWnd: HWND; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; external user32;

什么时候应该使用 ANSI 函数而不是调用 Unicode 函数?

【问题讨论】:

  • 这有点夸张。如果您正在处理以 ASCII 编码的窄字符串 - 例如,因为您已从网络套接字或纯文本文件中读取它 - 手动将其转换为 UTF-16 是没有意义的,这样您就可以调用 MessageBoxW 而不是消息框A。 (当然你必须知道你使用的是什么编码。如果窄字符串实际上是 UTF-8,那么你确实应该将它转换为 UTF-16 并调用 MessageBoxW。)

标签: windows function winapi unicode ansi


【解决方案1】:

就像发布的 cmets/answers 的(罕见)例外......

在需要和支持 UTF-8 的情况下,可以选择使用 ANSI 调用。例如,在设置为使用 TT 字体并在 chcp 65001 下运行的控制台中写入 UTF-8 字符串。

另一个奇怪的例外是主要实现为 ANSI 的函数,其中 Unicode“W”变体简单地转换为活动代码页中的窄字符串并调用“A”对应物。对于这样的函数,当一个窄字符串可用时,直接调用“A”变体可以节省冗余的双重转换。典型的例子是 OutputDebugString,它在 Windows 10 之前属于这一类(我刚刚注意到 https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx 提到对 WaitForDebugEventEx 的调用 - 仅在 Windows 10 之后可用 - 为 OutputDebugStringW 启用真正的 Unicode 输出)。

还有一些 API,即使是处理字符串,也是原生 ANSI。例如,GetProcAddress 仅存在于采用 LPCSTR 参数的 ANSI 变体中,因为导出表中的名称是窄字符串。

也就是说,大多数与字符串相关的 API 本身都是 Unicode,因此鼓励使用“W”变体。并非所有较新的 API 都不再具有“A”变体(例如CommandLineToArgvW)。来自马口https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx

Windows 原生支持 UI 元素、文件名等的 Unicode 字符串。 Unicode 是首选的字符编码,因为它支持所有字符集和语言。 Windows 使用 UTF-16 编码表示 Unicode 字符,其中每个字符都被编码为 16 位值。 UTF-16 字符称为宽字符,以区别于 8 位 ANSI 字符。

[...] 当 Microsoft 将 Unicode 支持引入 Windows 时,它通过提供两组并行的 API 来简化转换,一组用于 ANSI 字符串,另一组用于 Unicode 字符串。

[...] 在内部,ANSI 版本将字符串转换为 Unicode。 Windows 标头还定义了一个宏,该宏在定义预处理器符号 UNICODE 时解析为 Unicode 版本,否则解析为 ANSI 版本。

[...] Windows 中大多数较新的 API 只有 Unicode 版本,没有对应的 ANSI 版本。

[注意] 帖子经过编辑以添加最后两段。

【讨论】:

  • 这实际上是一个比接受的答案更好的答案。虽然这两个答案都是正确的,但这个答案确实更好地解决了这个问题。您可能需要补充一点,所有受支持的 Windows 版本(即基于 Windows NT 的系统)在使用 ANSI 版本的 API 调用时在内部使用 UTF-16LE,并从/转换为 ANSI 编码。这样你的答案是独立的,并且仍然有用,即使其他答案/cmets 确实被删除了。
  • @IInspectable 我的意图是指出一些例外情况,因为规则相当明显。但你是对的,我刚刚编辑了我的答案。
  • @IInspectable 感谢您的编辑。 CommandLineToArgvW 是 W-only API 的一个很好的例子,事实上至少可以追溯到 NT 3.51。
【解决方案2】:

要遵循的最简单的规则是:仅在没有 Unicode 变体的系统上使用 ANSI 变体。那是在 Windows 95、98 和 ME 上,它们是不支持 Unicode 的 Windows 版本。

如今,您不太可能针对此类版本,因此您很可能应该始终只使用 Unicode 变体。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
相关资源
最近更新 更多