Преобразование QString в BSTR и наоборот

Я хочу преобразовать QString в BSTR и наоборот.

Это то, что я пытаюсь преобразовать QString в BSTR:

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

и преобразовать BSTR в QString :

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

Это правильно? Другими словами, есть ли потеря данных? Если да, то какое правильное решение?


person Hesam Qodsi    schedule 25.03.2013    source источник


Ответы (3)


Вероятно, для этого вам следует использовать SysAllocString — BSTR также содержит префикс длины, который не включен в ваш код.

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

Кроме этого, здесь нечего терять - и BSTR, и QString используют 16-битную кодировку Unicode, поэтому преобразование между собой не должно вообще изменять внутренние буферы данных.

person j_kubik    schedule 26.03.2013

Чтобы преобразовать BSTR в QString, вы можете просто использовать функцию QString::fromUtf16:

BSTR bstrTest = SysAllocString(L"ConvertMe");
QString qstringTest = QString::fromUtf16(bstrTest);
person Rémy Greinhofer    schedule 31.10.2013
comment
Я получаю сообщение об ошибке C2664: "QString::fromUtf16": невозможно преобразовать параметр 1 из "BSTR" в "const ushort *" - person parsley72; 28.12.2013
comment
Может быть проблема с включением. Попробуйте включить ‹windows.h›. - person Rémy Greinhofer; 07.01.2014
comment
Нет, это не проблема включения. См. stackoverflow.com/questions/2395514/ — вам нужно преобразовать указатель wchar_t (тип BSTR) в указатель ushort, который ожидает QString::fromUtf16. Обратите внимание, однако, что на некоторых платформах wchar_t может быть длиннее, чем ushort — это вызовет неприятные проблемы. - person j_kubik; 05.02.2015

Строки BSTR состоят из двух частей: четыре байта для длины строки; и сам контент, который может содержать нулевые символы.

Короткий способ сделать это:

  1. Преобразуйте QString в двухбайтовую строку с завершающим нулем, используя QString::utf16. Не используйте toWCharArray, широкий символ отличается в Windows (два байта) и Linux (четыре байта) (я знаю, что COM - это технология Microsoft, но лучше быть уверенным)

  2. Используйте SysAllocString для создания строки BSTR, которая уже содержит длину строки.

  3. При необходимости освободите строку BSTR с помощью SysFreeString, когда вы закончите ее использовать. Пожалуйста, прочитайте следующую статью, чтобы узнать, когда вам нужно выпустить.

https://docs.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)

Чтобы преобразовать BSTR в QString, вы можете переинтерпретировать преобразование BSTR в указатель ushort, а затем использовать QString::fromUtf16. Не забудьте освободить BSTR, когда закончите с ним.

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

Следующая полезная статья очень хорошо объясняет строки BSTR.

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

person convexbytes    schedule 28.09.2018