Подтвердить что ты не робот

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;
}
4b9b3361

Ответ 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.