BSTR to std::string (std::wstring) and vice versa

ezpresso picture ezpresso · Jun 8, 2011 · Viewed 100.4k times · Source

While working with COM in C++ the strings are usually of BSTR data type. Someone can use BSTR wrapper like CComBSTR or MS's CString. But because I can't use ATL or MFC in MinGW compiler, is there standard code snippet to convert BSTR to std::string (or std::wstring) and vice versa?

Are there also some non-MS wrappers for BSTR similar to CComBSTR?

Update

Thanks to everyone who helped me out in any way! Just because no one has addressed the issue on conversion between BSTR and std::string, I would like to provide here some clues on how to do it.

Below are the functions I use to convert BSTR to std::string and std::string to BSTR respectively:

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

Answer

ildjarn picture ildjarn · Jun 8, 2011

BSTR to std::wstring:

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

 
std::wstring to BSTR:

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