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

ezp*_*sso 63 c++ string com

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

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

更新

感谢所有以任何方式帮助过我的人!仅仅因为没有人解决过BSTR和之间的转换问题std::string,我想在此提供一些关于如何做到这一点的线索.

下面是我用转换的功能BSTR,以std::stringstd::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, '\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;
}
Run Code Online (Sandbox Code Playgroud)

ild*_*arn 88

BSTRstd::wstring:

// given BSTR bs
assert(bs != nullptr);
std::wstring ws(bs, SysStringLen(bs));
Run Code Online (Sandbox Code Playgroud)

 
std::wstringBSTR:

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

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

  • @ildjam我很抱歉,如果这是一个菜鸟问题,但我开始在`BSTR`上进行"定义"(你需要以管理员的身份运行VS),而`BSTR`似乎只不过是`wchar_t*`.另一方面,我也发现[微软的文档](http://msdn.microsoft.com/en-us/library/windows/desktop/ms221240(v = vs.85).aspx),正如你所说,说这个构造函数可以处理嵌入的空字符.如果它包含的所有内容都是指向`wchar_t`的指针,那么这个构造函数如何找到`BSTR`的长度? (2认同)
  • @HerrKaputt:因为BSTR是在保留分配长度的特殊堆上分配的,并且允许在给定BSTR的情况下查询该长度. (2认同)
  • `NULL`是`BSTR`的**有效**状态,它相当于一个空字符串.所以代码应该是`std :: wstring(bs?bs:L"");` (2认同)
  • 这与个人喜好无关:“NULL”**是**一个有效的“BSTR”,您需要为其准备转换代码。这是“BSTR”书面合同的一部分。否则,您必须添加免责声明,指出:*“将大多数 `BSTR` 转换为 `std::wstring`!”* (2认同)
  • 语义上不存在混淆。“NULL”“BSTR”在语义上与空“BSTR”相同。这很容易映射到“std::wstring”。构造一个空的“std::wstring”是“NULL”“BSTR”的唯一正确且明显的转换。 (2认同)
  • @ildjarn 请参阅[此处第一个列表](https://blogs.msdn.microsoft.com/ericlippert/2003/09/12/erics-complete-guide-to-bstr-semantics/) 的第 1 点。如果代码库以与空 BSTR 不同的方式处理空 BSTR,这将是一个错误。 (2认同)

And*_*rsK 11

你也可以这样做

#include <comdef.h>

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

或者std :: string如果你愿意的话


小智 8

有一个名为_bstr_t. 它有有用的方法和重载运算符的集合。

例如,您可以轻松地从 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

  • 好答案!`std::string str = _bstr_t(theBSTR);` 很简单! (2认同)