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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6284524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:50:51  来源:igfitidea点击:

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

c++stringcom

提问by ezpresso

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

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

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

是否也有一些BSTR类似的非 MS 包装器CComBSTR

Update

更新

Thanks to everyone who helped me out in any way! Just because no one has addressed the issue on conversion between BSTRand 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 BSTRto std::stringand std::stringto BSTRrespectively:

以下是我用来分别转换BSTRstd::string和转换为的函数:std::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, '
// given BSTR bs
assert(bs != nullptr);
std::wstring ws(bs, SysStringLen(bs));
'); 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; }

回答by ildjarn

BSTRto std::wstring:

BSTRstd::wstring

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

 
std::wstringto BSTR:

 
std::wstringBSTR

#include <comdef.h>

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


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

回答by AndersK

You could also do this

你也可以这样做

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

or std::string if you prefer

或 std::string 如果您愿意

回答by AndersK

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

有一个名为_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::wstringoe std::string.

例如,您可以轻松地从 aconst wchar_t *或 a const char *just doing分配,_bstr_t bstr = L"My string";然后您可以将其转换回做const wchar_t * s = bstr.operator const wchar_t *();。您甚至可以将其转换回常规字符,const char * c = bstr.operator char *();然后您可以使用 theconst wchar_t *或 theconst char *来初始化一个新的std::wstringoe std::string

回答by Hans Passant

Simply pass the BSTR directly to the wstring constructor, it is compatible with a wchar_t*:

只需将 BSTR 直接传递给 wstring 构造函数,它就与 wchar_t* 兼容:

##代码##

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::string 需要先转换为 char*。这是有损的,因为 BSTR 存储了一个 utf-16 编码的 Unicode 字符串。除非你想用 utf-8 编码。您将在 ICU 库中找到执行此操作以及操作结果字符串的辅助方法。