Преобразование BSTR в UTF-8 - PullRequest
       1

Преобразование BSTR в UTF-8

0 голосов
/ 24 августа 2018

Я работаю с UIAutomation и борюсь с локализованными BSTR. Я нахожусь в Германии, поэтому есть несколько специальных персонажей, которые смешно представлены в BSTR. Я регистрирую информацию, и мне нужно, чтобы она была в UTF-8 для последующей обработки.

Я уже пробовал каждую версию ответов, которые я мог найти относительно WideCharToMultiByte, но это просто превращение забавного персонажа в еще более забавного. Буду очень признателен, если кто-нибудь скажет мне, что я делаю не так, это действительно беспокоит меня.

Итак, я попробовал обе следующие версии и получил оба раза этот результат (верхняя - конвертированная, нижняя - оригинальная):

Screenshot

Первое слово должно быть «Schaltfläche», а второе «Fünf».

Мой проверенный код:

BSTR* origin;
_bstr_t originWrapper(*origin);
char* originChar = originWrapper;
size_t len = strlen(originChar) + 1;
int room = MultiByteToWideChar(CP_ACP, 0, originChar, -1, NULL, 0);
wchar_t* unicodeString = (wchar_t*)malloc((sizeof(wchar_t))*room);
MultiByteToWideChar(CP_ACP, 0, originChar, -1, unicodeString, room);

int size_needed = WideCharToMultiByte(CP_UTF8, 0, unicodeString, -1, NULL, 0, NULL, NULL);
char* utf8Char = (char*) malloc(size_needed);
WideCharToMultiByte(CP_UTF8, 0, unicodeString, -1, utf8Char, size_needed, NULL, NULL);

и

BSTR* origin;
_bstr_t originWrapper(*origin);
int size_needed = WideCharToMultiByte(CP_UTF8, 0, originWrapper, SysStringByteLen(*origin), NULL, 0, NULL, NULL);
std::string resultingString(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, *origin, SysStringByteLen(*origin), &resultingString[0], size_needed, NULL, NULL);

1 Ответ

0 голосов
/ 24 августа 2018

BSTR - указатель на символьные данные UTF-16 (WCHAR), которым предшествует длина строки. Таким образом, ваша поездка через узкие струны ошибочна, вы должны прямо использовать WideCharToMultiByte:

std::string BSTRtoUTF8(BSTR bstr) {
    int len = SysStringLen(bstr);
    // special case because a NULL BSTR is a valid zero-length BSTR,
    // but regular string functions would balk on it
    if(len == 0) return "";
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, NULL, 0, NULL, NULL);
    std::string ret(size_needed, '\0');
    WideCharToMultiByte(CP_UTF8, 0, unicodeString, len, ret.data(), ret.size(), NULL, NULL);
    return ret;
}

Чтобы проверить правильность преобразования не выводите результат на консоль, так как он не поддерживает вывод UTF-8 по умолчанию (он интерпретирует узкие строки даже не так, как в CP_ACP , но в CP_OEM, пойди разберись). Вместо этого запишите выходные данные в файл и проверьте его с помощью надежного редактора, поддерживающего UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...