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
функционирует нормально для моих целей, потому что я не совсем разбираюсь во всех различных кодировках и прочем, но это совершенно другой вопрос, и кажется, что он решается во всем Интернете.
Ооооо, что-то не так с этим, кроме этой потенциальной проблемы?
С помощью _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
буфер в ответ, потому что вы предоставляете свой собственный.Других решений пока нет …