Могу ли я использовать класс _bstr_t для преобразования между многобайтовым и Unicode в Windows? (C ++)

BSTR это странный тип данных Windows с несколькими конкретными применениями, такими как функции COM. Согласно MSDN, он содержит WCHAR строка и некоторые другие вещи, такие как дескриптор длины. Windows также достаточно хорош, чтобы дать нам _bstr_t учебный класс, который заключает в капсулу BSTR; он заботится о распределении и освобождении и дает вам дополнительную функциональность. Она имеет четыре конструктора, в том числе тот, который принимает в char* и тот, который принимает в wchar_t*, MSDN описание первого: «Создает _bstr_t возражать SysAllocString создать новый BSTR объект, а затем инкапсулирует его. Этот конструктор сначала выполняет многобайтовое преобразование в Unicode. «

Он также имеет операторы который может извлечь указатель на строку как любой из char*, const char*, а также wchar_t*, и я почти уверен, что они заканчиваются нулем, что круто.

Я провел некоторое время, читая о том, как конвертировать между многобайтовым и Unicode, и я видел много разговоров о том, как использовать mbstowcs а также wcstomb, и как MultiByteToWideChar а также WideCharToMultiByte лучше, потому что кодировки могут отличаться, и бла-бла-бла. Все это отчасти похоже на головную боль, поэтому мне интересно, могу ли я просто построить _bstr_t и использовать операции для доступа к строкам, что было бы … намного меньшим количеством строк кода:

char* multi = "asdf";
_bstr_t bs = _bstr_t(mb);
wchar_t* wide = (wchar_t*)bs; // assume read-only

Я думаю, что мой интуитивный ответ на этот вопрос заключается в том, что мы не знаем, что Windows делает за кулисами, поэтому, если у меня возникнут проблемы с использованием mbstowcs/wcstomb (Я думаю, я действительно имею в виду mbstowcs_s/wcstomb_s) скорее, чем MultiByteToWideChar/WideCharToMultiByteЯ не должен рисковать, потому что возможно, что Windows использует их. (Это почти наверняка не использует последний, так как я не указываю здесь «кодовую страницу», что бы это ни было.) Честно говоря, я еще не уверен, рассматриваю ли я mbstowcs_s а также wcstomb_s функционирует нормально для моих целей, потому что я не совсем разбираюсь во всех различных кодировках и прочем, но это совершенно другой вопрос, и кажется, что он решается во всем Интернете.

Ооооо, что-то не так с этим, кроме этой потенциальной проблемы?

3

Решение

С помощью _bstr_t::_bstr_t(const char*) не совсем хорошая идея в производственном коде:

Создает _bstr_t возражать SysAllocString создать новый BSTR объект и инкапсулировать его. Этот конструктор сначала выполняет многобайтовое преобразование в Unicode. Если s2 слишком велик, ты [Так в оригинале] может генерировать ошибку переполнения стека. В такой ситуации преобразуйте char* к wchar_t с MultiByteToWideChar а затем позвоните wchar_t * конструктор.

Кроме того _bstr_t::operator wchar_t*() const throw() кажется едва полезным. Это просто для извлечения членов структуры, так что вы ограничены const:

Эти операторы могут использоваться для извлечения необработанных указателей на инкапсулированный объект Unicode или многобайтовый BSTR. Операторы возвращают указатель на фактический внутренний буфер, поэтому результирующая строка не может быть изменена.

Так _bstr_t это просто вспомогательный объект для инкапсуляции BSTRс, и посредственный в этом. Конвертация с использованием MultiByteToWideChar а также WideCharToMultiByte это гораздо лучший выбор по нескольким причинам:

  • Это намного менее склонно к краху.
  • Вы не получаете const буфер в ответ, потому что вы предоставляете свой собственный.
  • Названия этих функций являются информативными. Преобразование через конструктор и оператор приведения несвязанного типа не имеет.
2

Другие решения

Других решений пока нет …