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

发布于 2024-11-14 10:09:03 字数 1643 浏览 0 评论 0原文

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

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

更新

感谢所有以任何方式帮助我的人!正因为没有人解决 BSTRstd::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;
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

oО清风挽发oО 2024-11-21 10:09:03

BSTRstd::wstring

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

 
std::wstringBSTR

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

文档参考:

  1. std::basic_string::basic_string(const CharT*, size_type)
  2. std::basic_string>>::empty() const< /a>
  3. std::basic_string>>::data() const
  4. std::basic_string>>::size() const
  5. SysStringLen()
  6. SysAllocStringLen()

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()
愿得七秒忆 2024-11-21 10:09:03

有一个名为 _bstr_t 的 C++ 类。它具有有用的方法和一组重载运算符。

例如,您可以轻松地从 const wchar_t *const char * 进行分配,只需执行 _bstr_t bstr = L"My string"; 然后您可以通过执行 const wchar_t * s = bstr.operator const wchar_t *(); 将其转换回来。您甚至可以将其转换回常规 char const char * c = bstr.operator char *(); 然后您可以只使用 const wchar_t *>const char * 初始化一个新的 std::wstring oe std::string

There is a c++ class called _bstr_t. 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"; 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.

倦话 2024-11-21 10:09:03

如果您愿意,您也可以执行此操作

#include <comdef.h>

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

或 std::string

编辑:如果您的原始字符串包含多个嵌入的 \0,则此方法将不起作用。

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

EDIT: if your original string contains multiple embedded \0 this approach will not work.

悲歌长辞 2024-11-21 10:09:03

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

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

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

Simply pass the BSTR directly to the wstring constructor, it is compatible with a 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文