3

我正在将一些 Win32 代码移植到 C#,并且遇到了几个具有相同名称并使用相同结构的函数,只是它们以 A 和 W 结尾

例如:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool Shell_NotifyIconA(uint dwMessage, ref NOTIFYICONDATAA lpData);

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool Shell_NotifyIconW(uint dwMessage, ref NOTIFYICONDATAW lpData);

我在 C# 中看到了一些实现,它们在函数名称和相关结构中都省略了 A 和 W,如下所示:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool Shell_NotifyIcon(uint dwMessage, ref NOTIFYICONDATA lpData);

我想知道的是:

  1. A 和 W 分别代表什么?

  2. 在 C# 中,我应该使用 A 和 W 来实现如上所示的功能,还是省略 A 和 W 以支持单一实现是更好的做法?

4

1 回答 1

6

“A”后缀(代表 ANSI)表示该函数适用于输入的多字节字符串(可能其中的某些成员NOTIFYICONDATA是字符串),而“W”(表示“Wide”)表示该函数适用于输入 Unicode字符串。

在 Windows 中,最好尽可能使用 Unicode 字符串,因为这是操作系统内部使用的。因此,如果您的项目通过传递多字节字符串来调用 Windows API,最终将在内部进行到 Unicode 的转换(如果操作系统还返回一个字符串,则可能会再次转换回多字节),从而减慢速度。

通常,当函数的某个数据结构的两个版本X存在多字节和 Unicode 字符时,它们被赋予名称(分别)XA和一个做开关)。XWX#ifdef

我对 C# 的了解不够,无法回答问题的第二部分。

编辑:

正如David Heffernan所指出的,p/invoke 编组器会将名称解析为与属性中CharSet使用的名称匹配的名称。DllImport

于 2013-02-03T13:57:44.630 回答