3

I want to convert QString to BSTR and vice versa.

This is what i try to convert QString to BSTR :

std::wstring str_ = QString("some texts").toStdWString();
BSTR bstr_ = str_.c_str();

and to convert BSTR to QString :

BSTR bstr_;
wchar_t *str_ = bstr_;
QString qstring_ = QString::fromWCharArray(str_);

Is this correct? In other words is there any data lose? If yes, what is the correct solution?

Hesam Qodsi
  • 1,569
  • 3
  • 25
  • 38

4 Answers4

5

You should probably use SysAllocString to do this - BSTR also contains length prefix, which is not included with your code.

std::wstring str_ = QString("some texts").toStdWString();
BSTR bstr_ = SysAllocString(str_.c_str());

Other than that there isn't anything to be lost here - Both BSTR and QString use 16-bit Unicode encoding, so converting between each other should not modify internal data buffers at all.

j_kubik
  • 6,062
  • 1
  • 23
  • 42
3

To convert a BSTR to a QString you can simply use the QString::fromUtf16 function:

BSTR bstrTest = SysAllocString(L"ConvertMe");
QString qstringTest = QString::fromUtf16(bstrTest);
  • I get error C2664: 'QString::fromUtf16' : cannot convert parameter 1 from 'BSTR' to 'const ushort *' – parsley72 Dec 27 '13 at 23:25
  • Might be an include problem. Try including . – Rémy Greinhofer Jan 06 '14 at 21:11
  • No, it is not an include problem. See http://stackoverflow.com/questions/2395514/is-wchar-t-just-a-typedef-of-unsigned-short - you need to cast `wchar_t` pointer (BSTR typedef) to `ushort` pointer that `QString::fromUtf16` expects. Note however that on some platforms wchar_t might be longer than ushort - this will cause nasty problems. – j_kubik Feb 05 '15 at 20:26
1

BSTR strings consist on two parts: four bytes for the string length; and the content it self which can contain null characters.

The short way to do it would be:

  1. Convert QString to a two-byte null terminated string using QString::utf16. Do not use toWCharArray, a wide char is different on windows (two bytes) and linux (four bytes) (I know COM is microsoft tech, but better be sure)

  2. Use SysAllocString to create a BSTR string that contains the string length already.

  3. Optionally free the BSTR string with SysFreeString when you are done using it. Please read the following article to know when you need to release.

https://learn.microsoft.com/en-us/cpp/atl-mfc-shared/allocating-and-releasing-memory-for-a-bstr?view=vs-2017

BSTR bstr = ::SysAllocString(QString("stuff").utf16())
// use it
::SysFreeString(bstr)

To convert from BSTR to QString, you can reinterpret-cast BSTR to a ushort pointer, and then use QString::fromUtf16. Remember to free the BSTR when you are done with it.

QString qstr = QString::fromUtf16(reinterpret_cast<ushort*>(bstr));

The next useful article explains BSTR strings very well.

https://www.codeproject.com/Articles/13862/COM-in-plain-C-Part

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
convexbytes
  • 184
  • 1
  • 6
1
BSTR oldStr;

QString newStr{QString::fromWCharArray(oldStr)};
JenyaKh
  • 2,040
  • 17
  • 25