Назначение КомБСТР - PullRequest
       25

Назначение КомБСТР

1 голос
/ 17 ноября 2009

Я не совсем понимаю назначение строк COM. Какое из следующих строковых назначений является правильным. Зачем?

CComBSTR str;
.
.
Obj->str = L""  //Option1

ИЛИ должно быть

Obj->str = CComBSTR(L"")  //Option2

В чем причина

Ответы [ 4 ]

4 голосов
/ 17 ноября 2009

Реальное BSTR - это:

  • временно выделено из кучи COM (через SysAllocString() и семейство)
  • структура данных, в которой строковым данным предшествует их длина, сохраненная в 32-битном значении.
  • передается как указатель на пятый байт этой структуры данных, в которой находятся строковые данные.

См. Документацию: MSDN: BSTR

Большинство функций, которые принимают BSTR, не будут аварийно завершать работу, когда переданный BSTR создает простое назначение. Это приводит к путанице, поскольку люди наблюдают за тем, что кажется рабочим кодом, из которого они делают вывод, что BSTR может быть инициализирован так же, как и любой WCHAR *. Это неверный вывод.

Только действительные BSTRs могут быть переданы в интерфейсы OLE Automation.

Используя конструктор CComBSTR(), который вызывает SysAllocString(), ваш код создаст настоящий BSTR. Деструктор CComBSTR() позаботится о возврате выделенного хранилища в систему через SysFreeString().

Если вы передаете CComBSTR() API, который становится владельцем, обязательно вызовите метод .Detach(), чтобы убедиться, что BSTR не освобожден. BSTRs равны , а не ссылка считается (в отличие от объектов COM, которые есть), и поэтому попытка освободить BSTR более одного раза приведет к краху.

3 голосов
/ 17 ноября 2009

Если вы используете str = CComBSTR(L""), вы используете конструктор :

CComBSTR( LPCSTR pSrc );

Если вы используете str = L"", вы используете оператор присваивания :

CComBSTR& operator =(LPCSTR pSrc);

Они оба правильно инициализируют объект CComBSTR.

1 голос
/ 17 ноября 2009

Вариант 1 предпочтителен, потому что он выполняет только одно выделение для строки, тогда как вариант 2 делает 2 (не выдерживая создание нового временного объекта без особой причины). В отличие от типа bstr_t в VC ++, ATL не делает ссылочные подсчитанные строки, поэтому он скопирует всю строку.

1 голос
/ 17 ноября 2009

Лично я предпочел бы вариант 1, потому что для этого не требуется создавать новый CComBSTR объект. (Разумеется, неважно, что их код делает за кулисами - это отдельная история.)

...