简体   繁体   English

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

[英]BSTR to std::string (std::wstring) and vice versa

While working with COM in C++ the strings are usually of BSTR data type.在 C++ 中使用 COM 时,字符串通常是BSTR数据类型。 Someone can use BSTR wrapper like CComBSTR or MS's CString .有人可以使用BSTR包装器,例如CComBSTR或 MS 的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?但是因为我不能在 MinGW 编译器中使用 ATL 或 MFC,是否有标准代码片段可以将BSTR转换为std::string (或std::wstring ),反之亦然?

Are there also some non-MS wrappers for BSTR similar to CComBSTR ?是否还有一些类似于CComBSTRBSTR非 MS 包装器?

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.仅仅因为没有人解决BSTRstd::string之间的转换问题,我想在这里提供一些关于如何做到这一点的线索。

Below are the functions I use to convert BSTR to std::string and std::string to BSTR respectively:以下是我用来分别将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;
}

BSTR to std::wstring : BSTRstd::wstring

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


std::wstring to BSTR : 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()

You could also do this你也可以这样做

#include <comdef.h>

BSTR bs = SysAllocString("Hello");
std::wstring myString = _bstr_t(bs, false); // will take over ownership, so no need to free

or std::string if you prefer或 std::string 如果您愿意

EDIT: if your original string contains multiple embedded \0 this approach will not work.编辑:如果您的原始字符串包含多个嵌入的 \0 这种方法将不起作用。

There is a c++ class called _bstr_t .有一个名为_bstr_t的 c++ class 。 It has useful methods and a collection of overloaded operators.它具有有用的方法和一组重载运算符。

For example, you can easily assign from a const wchar_t * or a const char * just doing _bstr_t bstr = L"My string";例如,您可以轻松地从const wchar_t *const char *分配_bstr_t bstr = L"My string"; Then you can convert it back doing const wchar_t * s = bstr.operator const wchar_t *();然后你可以把它转换回来做const wchar_t * s = bstr.operator const wchar_t *(); . . You can even convert it back to a regular char const char * c = bstr.operator char *();您甚至可以将其转换回常规 char const char * c = bstr.operator char *(); You can then just use the const wchar_t * or the const char * to initialize a new std::wstring oe std::string .然后,您可以只使用const wchar_t *const char *来初始化新的std::wstringstd::string

Simply pass the BSTR directly to the wstring constructor, it is compatible with a wchar_t*:只需将 BSTR 直接传递给 wstring 构造函数,它与 wchar_t* 兼容:

BSTR btest = SysAllocString(L"Test");
assert(btest != NULL);
std::wstring wtest(btest);
assert(0 == wcscmp(wtest.c_str(), btest));

Converting BSTR to std::string requires a conversion to char* first.将 BSTR 转换为 std::string 需要先转换为 char*。 That's lossy since BSTR stores a utf-16 encoded Unicode string.这是有损的,因为 BSTR 存储了一个 utf-16 编码的 Unicode 字符串。 Unless you want to encode in utf-8.除非你想在 utf-8 中编码。 You'll find helper methods to do this, as well as manipulate the resulting string, in the ICU library.您将在 ICU 库中找到执行此操作以及操作结果字符串的辅助方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM