Я запутался в назначении строк COM. Какое из следующих назначений строк является правильным. Почему?
CComBSTR str;
.
.
Obj->str = L"" //Option1
ИЛИ должно быть
Obj->str = CComBSTR(L"") //Option2
Какова причина
Я запутался в назначении строк COM. Какое из следующих назначений строк является правильным. Почему?
CComBSTR str;
.
.
Obj->str = L"" //Option1
ИЛИ должно быть
Obj->str = CComBSTR(L"") //Option2
Какова причина
Если вы используете str = CComBSTR(L"")
, вы используете конструктор:
CComBSTR( LPCSTR pSrc );
Если вы используете str = L""
, вы используете оператор присваивания:
CComBSTR& operator =(LPCSTR pSrc);
Оба они правильно инициализируют объект CComBSTR.
Настоящий BSTR
это:
SysAllocString()
и семейство)См. документацию: MSDN: BSTR
Большинство функций, которые принимают BSTR
, не будут аварийно завершать работу при передаче BSTR, создающей простое назначение. Это приводит к путанице, поскольку люди наблюдают за тем, что кажется работающим кодом, из которого они делают вывод, что BSTR
можно инициализировать точно так же, как любой WCHAR *
. Этот вывод неверен.
В интерфейсы OLE Automation можно передавать только реальные BSTRs
.
Используя конструктор CComBSTR()
, который вызывает SysAllocString()
, ваш код создаст настоящий BSTR
. Деструктор CComBSTR()
позаботится о возврате выделенного хранилища в систему через SysFreeString()
.
Если вы передаете CComBSTR()
API, который становится владельцем, обязательно вызовите метод .Detach()
, чтобы гарантировать, что BSTR
не будет освобожден. BSTRs
не подсчитываются ссылки (в отличие от COM-объектов, которые учитываются), поэтому попытка освободить BSTR
более одного раза приведет к сбою.
Лично я бы предпочел вариант 1, потому что он не требует создания нового объекта CComBSTR
. (Конечно, делает ли это их код за кулисами, это другая история.)
Вариант 1 предпочтительнее, потому что он делает только одно выделение для строки, тогда как вариант 2 делает 2 (несмотря на создание нового временного объекта без особой причины). В отличие от типа bstr_t в VC++, тип ATL не делает ссылки на подсчитываемые строки, поэтому он будет копировать всю строку.