Shell_NotifyIconA / Shell_NotifyIconW ...有什么区别?

时间:2013-02-03 13:48:21

标签: c# c++ winapi interop pinvoke

我正在将一些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以支持单一实现?

1 个答案:

答案 0 :(得分:5)

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

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

通常,当多字节和Unicode字符存在函数X的某个数据结构的两个版本时,它们的名称(分别)为XAXW,并且条件别名X被定义为根据项目的设置解析为一个或另一个(转换#ifdef。)

我不太了解C#来回答问题的第二部分。

修改

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