BSTR到std :: string(std :: wstring),反之亦然

在C ++中使用COM时,string通常是BSTR数据types。 有人可以使用像CComBSTR或MS的CString BSTR包装。 但是因为我不能在MinGW编译器中使用ATL或MFC,有没有标准的代码片段将BSTR转换为std::string (或std::wstring ),反之亦然?

还有一些类似于CComBSTR BSTR非MS封装?

更新

感谢所有以任何方式帮助我的人! 只是因为没有人解决BSTRstd::string之间的转换问题,我想在这里提供一些关于如何做到这一点的线索。

下面是我用来将BSTR分别转换为std::stringstd::stringBSTR的函数:

 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; } 

BSTRstd::wstring

 // given BSTR bs assert(bs != nullptr); std::wstring ws(bs, SysStringLen(bs)); 

std::wstringBSTR

 // given std::wstring ws assert(!ws.empty()); BSTR bs = SysAllocStringLen(ws.data(), ws.size()); 

文件参考:

  1. std::basic_string<typename CharT>::basic_string(const CharT*, size_type)
  2. std::basic_string<>::empty() const
  3. std::basic_string<>::data() const
  4. std::basic_string<>::size() const
  5. SysStringLen()
  6. SysAllocStringLen()

你也可以这样做

 #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,如果你愿意的话

简单地将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编码的Unicodestring。 除非你想用UTF-8编码。 你会发现帮助者的方法来做到这一点,以及操纵ICU库中的结果string。

您可以使用:

 BSTR __fastcall StringToBSTR(String s) { const char* p = s.c_str(); size_t len = s.Length(); size_t sz = len * sizeof(wchar_t); wchar_t* tp; tp = new wchar_t[sz]; mbstowcs(tp, p, sz); std::wstring ws(tp); assert(!ws.empty()); BSTR bs = SysAllocStringLen(ws.data(), ws.size()); return(bs); } 

有一个名为_bstr_t的c ++类。 它有有用的方法和重载操作符的集合。

例如,你可以很容易地从一个const wchar_t *或一个const char *分配,只是做_bstr_t bstr = L"My string"; 然后你可以把它转换回来做const wchar_t * s = bstr.operator const wchar_t *(); 。 你甚至可以把它转换回正常的字符型const char * c = bstr.operator char *(); 然后你可以使用const wchar_t *或者const char *来初始化一个新的std::wstring oe std::string