by Michael S. Kaplan, published on 2005/06/21 14:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/06/21/431062.aspx
In the Suggestion Box, our good friend Serge Wautier of appTranslator fame (I'll blog about that tool another day!) asked:
What's the purpose of SHAnsiToUnicode() ? I mean... what advantage does it have over plain old MultiByteToWideChar() ?
Less parameters obviously. But is that it ?TIA,
Very good question, I have often wondered myself!
Just kidding. :-)
The fact is that in NLS we try to provide the full functionality that every function in the API is meant to support, via the various parameters and flags.
But even if you are inside of Microsoft, you are usually not trying to look at the whole big complicated functionality, you are trying to do a single task many times. So whether you are in the USER group or the SHELL group or the BCL or Office or somewhere else entirely, you write wrapper macros and functions. And many of the functions get published and become officially documented APIs. This is especially true in the Shell group where the SHLWAPI (Shell Lightweight API) exists and is incremented in every version with new wrappers and functions.
Which is not to say that SHUnicodeToAnsi and SHAnsiToUnicode are perfect functions for all occasions -- they assume that the source buffer is null terminated, and they do not allow you to select the code page (it is always the default system code page). You also cannot change the default character or choose what flags to pass in order to determine how to handle precomposed/composite characters. There is even a security warning in both functions, despite the fact that it guarantees NULL terminaton of the target string (if the length of the destination you pass does not match the buffer, bad things can happen).
But if you need to call the NLS APIs to do these conversions and do not want to have to remember all of the calling semantics, and if the way you want the conversion you happen is the same as the wrapper, then one of these functions may be perfect.
Sometimes, I wish that all of these wrappers explicitly documented how they called the NLS APIs; it would be much easier to choose the right function to use. But it is really not too hard to figure out what they are with a little experimentation and reading of the documentation. And if you are the sort of developer who worries about that sort of detail, then you are probably either calling the NLS functions directly or writing your own wrappers. So I have never pushed too hard for a huge doc. update. Plus, that would make it harder to make changes if there were bugs in the way it was implemented.
One disadvantage to these wrappers is that the parameters and calling semantics vary quite a bit. if you need to change the way you call the function or the flags you want to pass, your options are limited. I mean, if you are hasppily using String.StartsWith and String.EndsWith and suddenly need to start looking for a prefix and suffix with a width-insensitive comparison, the migration to CompareInfo.IsPrefix and CompareInfo.IsSuffix can be difficult, especially as you move from an instance method to a static one.
It is hard enough to make some people start using the "real" APIs all the time....
This post brought to you by "¥" (U+ffe5, a.k.a. FULLWIDTH WON SIGN)
# Rosyna on 21 Jun 2005 1:07 PM:
# Serge Wautier on 21 Jun 2005 2:22 PM:
# Michael S. Kaplan on 21 Jun 2005 5:29 PM:
# Michael S. Kaplan on 21 Jun 2005 5:29 PM:
# Dean Harding on 21 Jun 2005 7:34 PM:
# Rosyna on 21 Jun 2005 8:06 PM:
# Michael S. Kaplan on 21 Jun 2005 11:09 PM:
# Michael S. Kaplan on 21 Jun 2005 11:29 PM:
# Stuart Dootson on 22 Jun 2005 3:23 AM:
# Michael S. Kaplan on 22 Jun 2005 4:13 AM:
# Stuart Dootson on 24 Jun 2005 10:04 AM:
# Michael S. Kaplan on 24 Jun 2005 11:26 AM:
# Stuart Dootson on 28 Jun 2005 10:04 AM:
referenced by