Кодировка по умолчанию для преобразования варианта bstr в std :: string - PullRequest
8 голосов
/ 01 декабря 2009

У меня есть вариант bstr, который был извлечен из MSXML DOM, поэтому он есть в UTF-16. Я пытаюсь выяснить, какая кодировка по умолчанию происходит с этим преобразованием:

VARIANT vtNodeValue;
pNode->get_nodeValue(&vtNodeValue);
string strValue = (char*)_bstr_t(vtNodeValue);

Из тестирования я считаю, что кодировкой по умолчанию является Windows-1252 или Ascii, но я не уверен.

Кстати, это фрагмент кода, который я исправляю и преобразовываю вариант в строку wstring и перехожу к многобайтному кодированию с вызовом WideCharToMultiByte.

Спасибо!

Ответы [ 2 ]

10 голосов
/ 01 декабря 2009

Метод operator char* вызывает _com_util::ConvertBSTRToString(). Документация довольно бесполезна, но я предполагаю, что для преобразования используются текущие настройки локали.

Обновление:

Внутренне, _com_util::ConvertBSTRToString() вызывает WideCharToMultiByte, передавая ноль для всех параметров кодовой страницы и символов по умолчанию. Это то же самое, что и передача CP_ACP, что означает использование текущей настройки кодовой страницы ANSI системы (а не текущей настройки потока).

Если вы хотите избежать потери данных, вам, вероятно, следует позвонить WideCharToMultiByte напрямую и использовать CP_UTF8. Вы по-прежнему можете рассматривать строку как однобайтовую строку с нулевым символом в конце и использовать std::string, вы просто не можете трактовать байты как символы.

0 голосов
/ 01 декабря 2009

std::string само по себе не указывает / не содержит никакой кодировки. Это просто последовательность байтов. То же самое относится к std::wstring, который является просто последовательностью wchar_t s (двухбайтовые слова на Win32).

Преобразовав _bstr_t в char* с помощью оператора char *, вы просто получите указатель на необработанные данные. Согласно MSDN , эти данные состоят из широких символов, то есть wchar_t s, которые представляют UTF-16.

Я удивлен, что на самом деле это работает для построения std::string из этого; вы не должны проходить мимо первого нулевого байта (что произойдет в ближайшее время, если ваша исходная строка будет английской).

Но поскольку wstring является строкой wchar_t, вы должны иметь возможность создать ее непосредственно из _bstr_t следующим образом:

_bstr_t tmp(vtNodeValue);
wstring strValue((wchar_t*)tmp, tmp.length());

(я не уверен насчет length; это количество байтов или количество символов?) Тогда у вас будет wstring, закодированный в UTF-16, по которому можно позвонить WideCharToMultiByte.

...