std::string (std::wstring),反之亦然。

时间:2023-02-11 20:19:07

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?

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

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

BSTR是否也有类似于CComBSTR的非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.

感谢所有以任何方式帮助我的人!就因为没有人讨论过BSTR和std::string之间的转换问题,我想在这里提供一些关于如何转换的线索。

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

下面是我将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;
}

4 个解决方案

#1


74  

BSTR to std::wstring:

型std::wstring:

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

 
std::wstring to BSTR:

std::wstring型:

// 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 < typename图表>::basic_string(const图*,size_type)
  3. std::basic_string<>::empty() const
  4. std::basic_string < >::空()常量
  5. std::basic_string<>::data() const
  6. std::basic_string < >::数据()常量
  7. std::basic_string<>::size() const
  8. std::basic_string < >::大小()常量
  9. SysStringLen()
  10. SysStringLen()
  11. SysAllocStringLen()
  12. SysAllocStringLen()

#2


8  

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 if you prefer

#3


3  

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. That's lossy since BSTR stores a utf-16 encoded Unicode string. Unless you want to encode in utf-8. You'll find helper methods to do this, as well as manipulate the resulting string, in the ICU library.

将BSTR转换为std::字符串首先需要转换为char*。这是有损的,因为BSTR存储utf-16编码的Unicode字符串。除非你想用utf-8编码。您将在ICU库中找到帮助器方法来实现这一点,以及操作结果字符串。

#4


1  

There is a c++ class called _bstr_t. It has useful methods and a collection of overloaded operators.

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

For example, you can easily assign from a const wchar_t * or a const char * just doing _bstr_t bstr = L"My string"; Then you can convert it back doing 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 *(); 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 *中分配_bstr_t bstr = L“My string”;然后你可以把它转换回const wchar_t * s = bstr。运营商const wchar_t *();。您甚至可以将它转换回普通的char const char * c = bstr。运营商char *();然后,您可以使用const wchar_t *或const char *初始化一个新的std:::wstring oe std::string。

#1


74  

BSTR to std::wstring:

型std::wstring:

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

 
std::wstring to BSTR:

std::wstring型:

// 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 < typename图表>::basic_string(const图*,size_type)
  3. std::basic_string<>::empty() const
  4. std::basic_string < >::空()常量
  5. std::basic_string<>::data() const
  6. std::basic_string < >::数据()常量
  7. std::basic_string<>::size() const
  8. std::basic_string < >::大小()常量
  9. SysStringLen()
  10. SysStringLen()
  11. SysAllocStringLen()
  12. SysAllocStringLen()

#2


8  

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 if you prefer

#3


3  

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. That's lossy since BSTR stores a utf-16 encoded Unicode string. Unless you want to encode in utf-8. You'll find helper methods to do this, as well as manipulate the resulting string, in the ICU library.

将BSTR转换为std::字符串首先需要转换为char*。这是有损的,因为BSTR存储utf-16编码的Unicode字符串。除非你想用utf-8编码。您将在ICU库中找到帮助器方法来实现这一点,以及操作结果字符串。

#4


1  

There is a c++ class called _bstr_t. It has useful methods and a collection of overloaded operators.

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

For example, you can easily assign from a const wchar_t * or a const char * just doing _bstr_t bstr = L"My string"; Then you can convert it back doing 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 *(); 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 *中分配_bstr_t bstr = L“My string”;然后你可以把它转换回const wchar_t * s = bstr。运营商const wchar_t *();。您甚至可以将它转换回普通的char const char * c = bstr。运营商char *();然后,您可以使用const wchar_t *或const char *初始化一个新的std:::wstring oe std::string。