BSTR转换为UTF-8

时间:2018-08-24 08:12:47

标签: c++ windows utf-8

我正在使用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 :(得分:4)

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输出(它解释窄字符串,甚至不像{{ 1}},但在CP_ACP中,请加上数字)。而是将输出写入文件,并使用支持UTF-8的可靠编辑器进行检查。