BSTR в std:: string (std::wstring) и наоборот



при работе с COM в C++ строки обычно BSTR тип данных. Кто-то может использовать BSTR фантик как CComBSTR или МС CString. Но поскольку я не могу использовать ATL или MFC в компиляторе MinGW, есть ли стандартный фрагмент кода для преобразования BSTR to std::string (или std::wstring) и наоборот?



есть ли также некоторые не-MS обертки для BSTR аналогично CComBSTR?



обновление



спасибо всем, кто помог мне в любом случае! Просто потому, что никто не рассматривал вопрос о преобразовании между BSTR и std::string, Я хотел бы представить здесь некоторые подсказки о том, как это сделать.



Ниже приведены функции, которые я использую, чтобы преобразовать BSTR to 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, '');
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;
}
659   4  

4 ответов:

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:

  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()

вы также можете сделать это

#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 если вы предпочитаете

просто передайте 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. Если вы не хотите кодировать в UTF-8. Вы найдете вспомогательные методы для этого, а также манипулировать результирующей строкой, в библиотеке ICU.

существует класс c++ под названием _bstr_t. Он имеет полезные методы и набор перегруженных операторов.

например, вы можете легко назначить с 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.

Comments

    Ничего не найдено.