" писал(а):Давай на пальцах - в чем заключается удаление варианта содержащего IDispatch? Вызывающий очевидно должен сделать QueryInterface(IID_IDispatch) или AddRef(), увеличив счетчик ссылок на объект на единицу, а получающий - сделать Release() когда интерфейс больше не нужен чтобы не случился Interface Leak. VariantClear() очевидно делает Release если вариант имеет тип VT_UNKNOWN или VT_DISPATCH.
Нет, не так. Вот схема:
Код: Выделить всё
// Вызывающий создал объект и положил его в смартпоинтер (Количество ссылок 0+1 = 1)
// Вызывающий поместил объект в Вариант (1+1 = 2)
// Вызов метода
////// Получающий проанализировал данные
////// Скажем ему нужен полученный объект, значит он сохраняет его в смартпоинтере-мэмбере, это влечёт за собой AddRef (2+1 = 3)
// Конец вызова метода
// Вызывающий удаляет Вариант (3-1 = 2)
// Вызыващий удаляет смарпоинтер (2-1 = 1)
И так: если объект был не интересен Получающему, то на последней строчке схемы объект умрёт. Но так, как Получающему он был интересен и Получающий сделал ему AddRef для дальнейшей работы с ним - объект по прежнему жив с количеством ссылок = 1.
Объект умрёт лишь тогда, когда станет неинтересен Получающему и он сделает для него Release. Это может произойти насильно, либо во время смерти Получающего, когда отработает смартпоинтер-мэмбэр, который держит наш объект.
Такая схема работы с инпут параметрами является классической.
Ситуации, когда Вызывающий делает AddRef, а Получающий делает соответствующий Release быть не должно. Это грубое нарушение концепции COM.