BSTR à std:: string (std:: wstring) et vice versa

Lorsque vous travaillez avec COM en C++ , les chaînes sont généralement de type BSTR. Quelqu'un peut utiliser BSTR wrapper comme CComBSTR, ou MME de CString. Mais parce que je ne peux pas utiliser ATL ou MFC dans le compilateur MinGW, existe-t-il un extrait de code standard pour convertir BSTR en std::string (ou std::wstring) et vice versa?

Y a - t-il aussi des wrappers Non-MS pour BSTR similaires à CComBSTR?

Mettre à jour

Merci à tous ceux qui m'ont aidé de quelque façon que ce soit! Tout simplement parce que personne n'a abordé la question de la conversion entre BSTR et std::string, je voudrais présenter ici quelques indices sur la façon de le faire.

Ci-Dessous sont les fonctions que j'utilise pour convertir les BSTR à std::string et std::string à BSTR, respectivement:

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, '');
    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;
}
56
demandé sur ezpresso 2011-06-09 00:02:09

4 réponses

BSTR de std::wstring:

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


std::wstring de BSTR:

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

Doc de réf:

  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()
76
répondu ildjarn 2018-03-09 04:46:52

Vous pouvez également faire ceci

#include <comdef.h>

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

Ou std::string si vous préférez

9
répondu Anders 2015-04-10 14:30:26

Il suffit de passer le BSTR directement au constructeur wstring, il est compatible avec un wchar_t*:

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

La conversion de BSTR en std:: string nécessite d'abord une conversion en char*. C'est avec perte puisque BSTR stocke une chaîne Unicode encodée en utf-16. Sauf si vous voulez encoder en utf-8. Vous trouverez des méthodes d'aide pour ce faire, ainsi que de manipuler la chaîne résultante, dans la bibliothèque ICU.

3
répondu Hans Passant 2011-06-08 20:38:47

Il existe une Classe C++ appelée _bstr_t. Il a des méthodes utiles et une collection d'opérateurs surchargés.

Par exemple, vous pouvez facilement attribuer à partir d'un const wchar_t * ou const char * juste faire _bstr_t bstr = L"My string";, Alors vous pouvez convertir faire const wchar_t * s = bstr.operator const wchar_t *();. Vous pouvez même convertir à un régulière char const char * c = bstr.operator char *(); ensuite, Vous pouvez simplement utiliser le const wchar_t * ou const char * pour initialiser une nouvelle std::wstring oe std::string.

1
répondu 2017-06-27 13:49:30