web-dev-qa-db-ja.com

BSTRからstd :: string(std :: wstring)およびその逆

C++でCOMを操作している間、文字列は通常BSTRデータ型です。誰かがBSTRやMSのCComBSTRのようなCStringラッパーを使用できます。しかし、MinGWコンパイラでATLまたはMFCを使用できないため、BSTRstd::string(またはstd::wstring)に、またはその逆に変換する標準的なコードスニペットはありますか?

BSTRに似たCComBSTRのMS以外のラッパーもありますか?

更新

何らかの形で私を助けてくれたみんなに感謝します! BSTRstd::stringの間の変換に関する問題に誰も対処していないという理由だけで、ここでそれを行う方法に関するいくつかの手がかりを提供したいと思います。

以下は、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, '\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;
}
61
ezpresso

BSTRから_std::wstring_へ:

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


_std::wstring_からBSTR

_// 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()
86
ildjarn

これもできます

#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

10
Anders

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ライブラリには、結果の文字列を操作するだけでなく、これを行うヘルパーメソッドがあります。

3
Hans Passant

_bstr_tというc ++クラスがあります。便利なメソッドとオーバーロードされた演算子のコレクションがあります。

たとえば、const wchar_t *またはconst char *から簡単に割り当てることができ、_bstr_t bstr = L"My string";を実行すると、const wchar_t * s = bstr.operator const wchar_t *();を実行して元に戻すことができます。それを通常の文字const char * c = bstr.operator char *();に戻すこともできます。その後、const wchar_t *またはconst char *を使用して、新しいstd::wstring oe std::stringを初期化できます。

3
user2074102