Не слушай Анонимов — они ответственности не несут!
Потому как использование [out] параметров в целях [in] может караться СОМом существеннее, чем насмешкой в форуме.
АК> // так ?
АК> *ID = WideString(L"Unknown Device").Copy();
АК> // или так ?
АК> *ID = WideString(L"Unknown Device").Detach();
Различие этих двух способов — в дополнительных издержках при Copy на выделение памяти, которых можно (и нужно бы) избежать. Если используется временная переменная (как в твоем случае), то лучше использовать Detach. Если же переменная глобальная, то, разумеется, Detach не подходит и остается лишь Copy.
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, Алексей К, Вы писали:
Vi2>Не слушай Анонимов — они ответственности не несут! Vi2>Потому как использование [out] параметров в целях [in] может караться СОМом существеннее, чем насмешкой в форуме.
Vi2>
АК>> // так ?
АК>> *ID = WideString(L"Unknown Device").Copy();
АК>> // или так ?
АК>> *ID = WideString(L"Unknown Device").Detach();
Vi2>Различие этих двух способов — в дополнительных издержках при Copy на выделение памяти, которых можно (и нужно бы) избежать. Если используется временная переменная (как в твоем случае), то лучше использовать Detach. Если же переменная глобальная, то, разумеется, Detach не подходит и остается лишь Copy.
А если подумать ?.
STDMETHODIMP TMedDeviceImpl::GetDeviceID(BSTR* ID) //здесь это метод автоматизации, т.е. 'BSTR* ID' может содержать все что угодно.
надо обязательно освободить занимаемую память перед распределением новой.
дальше : возможно методы WideString .Copy() и .Detach() делают что либо похожее —
но
А>STDMETHODIMP TMedDeviceImpl::GetDeviceID(BSTR* ID)
А> //здесь это метод автоматизации, т.е. 'BSTR* ID' может содержать все что угодно.
Итак, этому варианту в С соответствует ДВА варианта в IDL — GetDeviceID([in,out]BSTR* ID) и GetDeviceID([out]BSTR* ID) с возможным retval-ом. Схемы работы сервера в этих случаях разный.
А>надо обязательно освободить занимаемую память перед распределением новой.
В первом варианте нужно освобождать, а во втором — нет. И клиентский код для второго случая без маршаллинга
BSTR devID; GetDeviceID(&devID);
вынесет клиента, хотя он, клиент, делает все правильно. Потому как devID не проинициализирован и не должен быть проинициализирован.
А>(лучше вообще не советовать , чем путать , б...)
Если есть какие-то нюансы работы с параметрами в системе классов T**** и WideString, то, наверное, лучше уточнить эти нюансы.
А>при всем уважении меня ты только запутал.
А>кстати ,а уточни : что лучше использовать в Builder'e, в COM'ах для передачи параметров ADO: TVariant , CComVariant либо что-то еще.
Я не знаю насчет Builder'а — не работал с ним.
Я писал просто о том, что главное — это IDL описание интерфейса. Это контракт между сервером и клиентом. Если параметр имеет [in] составляющую, то клиент обязан инициализировать параметр. Если параметр имеет [out] составляющую, то сервер обязан вернуть правильный параметр. Если параметр имеет и [in], и [out] составляющую, то клиент обязан установить, а сервер обязан вернуть правильные значения, возможно, изменив переданное значение.
Все остальные манипуляции считаются запрещенными. Это изменение параметров [in] или чтение параметров [out].
PS
Это все, конечно, не касается самых первых указателей. Т.е. [out]long* p или [out]BSTR* p, p как указатель на нечто может быть считан. Однако значение. на которое он ссылается, является объектом в вопросе. Т.е. *p не может быть использовано для чтения.