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

时间:2011-06-08 20:02:09

标签: c++ string com

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

是否还有BSTR的某些非MS包装器类似于CComBSTR

更新

感谢所有以任何方式帮助过我的人!仅仅因为没有人解决BSTRstd::string之间的转换问题,我想在此提供一些有关如何执行此操作的线索。

以下是我用来分别将BSTR转换为std::stringstd::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;
}

4 个答案:

答案 0 :(得分:83)

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());

Doc refs:

  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()

答案 1 :(得分:9)

您也可以这样做

#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如果您愿意

答案 2 :(得分:3)

只需将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库中操作生成的字符串。

答案 3 :(得分:3)

有一个名为<root xmlns="http://rootschema"><metadata><ese:record xmlns:ese="http://www.europeana.eu/schemas/ese/" schemaLocation="http://www.europeana.eu/schemas/ese/ http://www.europeana.eu/schemas/ese/ESE-V3.4.xsd"> <metadata> </root> 的c ++类。它有很多有用的方法和一组重载的运算符。

例如,您可以轻松地从_bstr_tconst 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 * oe std::wstring。< / p>