问题
I am porting some Win32 code to C#, and have come accross several functions which have the same names and use the same structures except that they end with A and W
For example:
[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);
I have seen some implementations in C# which omit the A and W from both the function name, and the associated structure, like so:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool Shell_NotifyIcon(uint dwMessage, ref NOTIFYICONDATA lpData);
What I want to know is:
What do A and W denote?
In C#, should I implement the functions as shown above, using both A and W, or is it better practice to omit A and W in favour of having a single implementation?
回答1:
The "A" suffix (which stands for ANSI) means that the function works with input multi-byte strings (probably some members of NOTIFYICONDATA
are strings), while "W" (which stands for "Wide") means the function works with input Unicode strings.
In Windows, it is better to work with Unicode strings whenever possible, because that's what the OS internally uses. Thus, if your project invokes a Windows API by passing a multi-byte string, a conversion to Unicode will eventually happen internally (and possibly a second conversion back to multi-byte if the OS also returns you a string), slowing things down.
Usually, when two versions of a certain data structure of function X
exist for multi-byte and Unicode characters, they are given the names (respectively) XA
and XW
, and a conditional alias X
is defined to resolve into one or the other based on your project's settings (an #ifdef
does the switch).
I do not know enough about C# to answer the second part of the question.
EDIT:
As pointed out by David Heffernan, the p/invoke marshaller will resolve the name to the one that matches the CharSet
used in the DllImport
attribute.
来源:https://stackoverflow.com/questions/14673155/shell-notifyicona-shell-notifyiconw-whats-the-difference