[英]Portable conversion of std::string to std::wstring and vice versa?
[英]BSTR to std::string (std::wstring) and vice versa
在 C++ 中使用 COM 时,字符串通常是BSTR
数据类型。 有人可以使用BSTR
包装器,例如CComBSTR
或 MS 的CString
。 但是因为我不能在 MinGW 编译器中使用 ATL 或 MFC,是否有标准代码片段可以将BSTR
转换为std::string
(或std::wstring
),反之亦然?
是否还有一些类似于CComBSTR
的BSTR
非 MS 包装器?
感谢所有以任何方式帮助我的人! 仅仅因为没有人解决BSTR
和std::string
之间的转换问题,我想在这里提供一些关于如何做到这一点的线索。
以下是我用来分别将BSTR
转换为std::string
和std::string
转换为BSTR
的函数:
std::string ConvertBSTRToMBS(BSTR bstr)
{
int wslen = ::SysStringLen(bstr);
return ConvertWCSToMBS((wchar_t*)bstr, wslen);
}
std::string ConvertWCSToMBS(const wchar_t* pstr, long wslen)
{
int len = ::WideCharToMultiByte(CP_ACP, 0, pstr, wslen, NULL, 0, NULL, NULL);
std::string dblstr(len, '\0');
len = ::WideCharToMultiByte(CP_ACP, 0 /* no flags */,
pstr, wslen /* not necessary NULL-terminated */,
&dblstr[0], len,
NULL, NULL /* no default char */);
return dblstr;
}
BSTR ConvertMBSToBSTR(const std::string& str)
{
int wslen = ::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
str.data(), str.length(),
NULL, 0);
BSTR wsdata = ::SysAllocStringLen(NULL, wslen);
::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
str.data(), str.length(),
wsdata, wslen);
return wsdata;
}
BSTR
到std::wstring
:
// given BSTR bs
assert(bs != nullptr);
std::wstring ws(bs, SysStringLen(bs));
std::wstring
到BSTR
:
// given std::wstring ws
assert(!ws.empty());
BSTR bs = SysAllocStringLen(ws.data(), ws.size());
文档参考:
你也可以这样做
#include <comdef.h>
BSTR bs = SysAllocString("Hello");
std::wstring myString = _bstr_t(bs, false); // will take over ownership, so no need to free
或 std::string 如果您愿意
编辑:如果您的原始字符串包含多个嵌入的 \0 这种方法将不起作用。
有一个名为_bstr_t
的 c++ class 。 它具有有用的方法和一组重载运算符。
例如,您可以轻松地从const wchar_t *
或const char *
分配_bstr_t bstr = L"My string";
然后你可以把它转换回来做const wchar_t * s = bstr.operator const wchar_t *();
. 您甚至可以将其转换回常规 char const char * c = bstr.operator char *();
然后,您可以只使用const wchar_t *
或const char *
来初始化新的std::wstring
或std::string
。
只需将 BSTR 直接传递给 wstring 构造函数,它与 wchar_t* 兼容:
BSTR btest = SysAllocString(L"Test");
assert(btest != NULL);
std::wstring wtest(btest);
assert(0 == wcscmp(wtest.c_str(), btest));
将 BSTR 转换为 std::string 需要先转换为 char*。 这是有损的,因为 BSTR 存储了一个 utf-16 编码的 Unicode 字符串。 除非你想在 utf-8 中编码。 您将在 ICU 库中找到执行此操作以及操作结果字符串的辅助方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.