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:
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)
Use SysAllocString to create a BSTR string that contains the string length already.
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