setlocale() не засяга ConvertBSTRToString(), но настройката за цялата система го прави?

Дадено: ASP.Net приложение, което използва наследена COM библиотека наследена COM библиотека, която е изградена без Unicode (MBCS) Windows 2008 dev сървър, на който работи всичко

Необходимо е: поддръжка на потребители на уеб приложения в различни локали

Тест:

1) Зададох системния локал на сървъра на руски и тествах руски входове.

.NET ги третира като UTF16, предава на COM като BSTR, COM го преобразува в char* с помощта на ConvertBSTRToString и текущия локал (руски), записва ги във файл, чете ги във файл, предава обратно на .NET и получава правилни резултати.

2) Връщам системния локал на САЩ/английски, добавям код или към приложението ASP.NET, или към самия COM, за да задам локала на руски изрично, локалът е зададен успешно (запитвам го и получавам обратно руски), COM получава UTF -16 BSTR, използва ConvertBSTRToString, за да го преобразува в char* и получава въпросителни знаци "???"!

Защо?? Каква е разликата между наличието на системна локална настройка и извикването на setlocale() в процеса? Какъв е смисълът на setlocale тогава? Използва ли ConvertBSTRToString нещо различно от текущия локал?

Аз също се опитах да направя

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

вътре в извикващия ASP.NET обект на COM и се опита да направи

setlocale(LC_ALL, "Russian");

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

заедно с setlocale() вътре в COM библиотеката; без ефект.

Наистина бих се радвал на принос за това!


person MK.    schedule 13.07.2010    source източник


Отговори (1)


От документите не става ясно какво използва ConvertBSTRToString() за определяне на текущия локал. Но можете да бъдете почти сигурни, че това не е локалът на CRT, зададен от setlocale(). Почти със сигурност трябва да извикате SetThreadLocale().

Използвайте WideCharToMultiByte(), за да го направите по-малко предположение.

person Hans Passant    schedule 13.07.2010
comment
Благодаря, опитах това и актуализирах въпроса. Изглежда, че няма разлика. - person MK.; 13.07.2010
comment
Благодаря ви, прав сте. ConvertBSTRToString() извиква WideCharToMultiByte() под капака, игнорирайки настройката за локал. Извикването на WideCharToMultiByte() изрично решава проблема (с изключение на това, че кодът разчита на счупения ConvertBSTRToString() навсякъде и коригирането, което ще бъде нетривиално, благодаря, Microsoft) - person MK.; 14.07.2010