簡體   English   中英

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

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

在 C++ 中使用 COM 時,字符串通常是BSTR數據類型。 有人可以使用BSTR包裝器,例如CComBSTR或 MS 的CString 但是因為我不能在 MinGW 編譯器中使用 ATL 或 MFC,是否有標准代碼片段可以將BSTR轉換為std::string (或std::wstring ),反之亦然?

是否還有一些類似於CComBSTRBSTR非 MS 包裝器?

更新

感謝所有以任何方式幫助我的人! 僅僅因為沒有人解決BSTRstd::string之間的轉換問題,我想在這里提供一些關於如何做到這一點的線索。

以下是我用來分別將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;
}

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

你也可以這樣做

#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 這種方法將不起作用。

有一個名為_bstr_t的 c++ class 。 它具有有用的方法和一組重載運算符。

例如,您可以輕松地從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::wstringstd::string

只需將 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 庫中找到執行此操作以及操作結果字符串的輔助方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM