views:

18

answers:

1

Given: ASP.Net application which uses a legacy COM library legacy COM library which is built without Unicode (MBCS) Windows 2008 dev server on which it all runs

Needed: support web app users in different locales

Test:

1) I set the system locale on the server to Russian and tested Russian inputs.

.NET treats them as UTF16, passes on to COM as BSTR, COM converts it to char* using ConvertBSTRToString and current locale (russian), writes them to file, reads them to file, passes back to .NET and getting correct results.

2) I set the system locale back to US/English, add code to either ASP.NET app or the COM itself to set locale to Russian explicitly, the locale is set successfully (I query it and get Russian back), COM receives UTF-16 BSTR, uses ConvertBSTRToString to convert it to char* and gets question marks "???"!

Why?? What's the difference between having system wide locale setting and calling setlocale() in the process? What is the point of setlocale then? Is ConvertBSTRToString using something other than current locale?

I have also tried doing

    System.Threading.Thread.CurrentThread.CurrentCulture = 
new System.Globalization.CultureInfo("ru-RU");

inside the ASP.NET caller of the COM object and tried doing

setlocale(LC_ALL, "Russian");

        SetThreadLocale(
MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT));

along side the setlocale() inside the COM library; no effect.

I would really appreciate inputs on that!

+1  A: 

It isn't clear from the docs what ConvertBSTRToString() uses to determine the current locale. But you can be pretty sure that it is not the CRT locale as set by setlocale(). You almost certainly need to call SetThreadLocale().

Use WideCharToMultiByte() to make it less of a guess.

Hans Passant
Thanks, I tried that and updated the question. Doesn't seem to make a difference.
MK
@MK: answer updated.
Hans Passant
Thank you, you are correct. ConvertBSTRToString() calls WideCharToMultiByte() under the hood, ignoring the locale setting. Calling WideCharToMultiByte() explicitly solves the problem (except the code relies on the broken ConvertBSTRToString() all over the place and fixing that is going to be non-trivial, thanks, Microsoft)
MK