BSTR до std::string (std:: wstring) и наоборот
При работе с COM в С++ строки обычно имеют тип данных BSTR
. Кто-то может использовать обертку BSTR
, например CComBSTR
или MS CString
. Но поскольку я не могу использовать ATL или MFC в компиляторе MinGW, существует ли стандартный фрагмент кода для преобразования BSTR
в std::string
(или std::wstring
) и наоборот?
Существуют также некоторые не-MS-обертки для BSTR
, похожие на CComBSTR
?
Update
Спасибо всем, кто мне помог! Просто потому, что никто не обратился к вопросу о преобразовании между BSTR
и std::string
, я хотел бы здесь дать некоторые подсказки о том, как это сделать.
Ниже перечислены функции, которые я использую для преобразования BSTR
в std::string
и std::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;
}
Ответы
Ответ 1
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());
Doc refs:
Ответ 2
Вы также можете сделать это
#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, если вы предпочитаете
Ответ 3
Просто передайте 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 хранит строку Unicode, кодированную utf-16. Если вы не хотите кодировать в utf-8. Вы найдете вспомогательные методы для этого, а также обработать результирующую строку в библиотеке ICU.
Ответ 4
Вы можете использовать:
BSTR __fastcall StringToBSTR(String s)
{
const char* p = s.c_str();
size_t len = s.Length();
size_t sz = len * sizeof(wchar_t);
wchar_t* tp;
tp = new wchar_t[sz];
mbstowcs(tp, p, sz);
std::wstring ws(tp);
assert(!ws.empty());
BSTR bs = SysAllocStringLen(ws.data(), ws.size());
return(bs);
}
Ответ 5
Существует класс С++ под названием _bstr_t
. Он имеет полезные методы и набор перегруженных операторов.
Например, вы можете легко назначить из 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
.