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

ser*_*0ne 1 c# c++ pinvoke winapi interop

我正在将一些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);
Run Code Online (Sandbox Code Playgroud)

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

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

我想知道的是:

  1. A和W表示什么?

  2. 在C#中,我应该使用A和W来实现上面显示的函数,还是更好的做法是省略A和W以支持单个实现?

And*_*owl 5

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

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

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

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

编辑:

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