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