2013-06-13 2 views
1

В настоящее время я работаю на COM-сервере (используя ATL), который будет использоваться закрытым источником VB . До сих пор все работает, но я хочу, чтобы убедиться, что никаких утечек не там ... поэтому мой вопрос:Увеличивает ли IDispatch :: Invoke (DISPATCH_PROPERTYGET) счетчик ссылок на интерфейсе IDispatch?

Должен ли я позвонить AddRef и/или Release на указатель IDispatch, полученный с помощью:

VARIANT pVar; 
IDispatch->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, 
        &dispparamsNoArgs, &pVar, NULL, NULL); 

ответ

2

Если у вашего pVar есть указатель на интерфейс (IUnknown* или IDispatch*), вы получите его AddRef 'уже подано. Вы несете ответственность за выполнение соответствующего выпуска, когда вы закончите, что вы обычно делаете косвенно, просто очищая вариант: через VariantClear.

Функция очищает VARIANTARG, устанавливая поле vt в VT_EMPTY. Текущее содержимое VARIANTARG выпущено первым. [...] Если vtfield является VT_DISPATCH, объект освобождается. [...]

Кстати, нет необходимости использовать Invoke для чтения свойства в ATL. У вас есть славные помощники:

CComPtr<IDispatch> pDispatch; 
CComVariant vFoo; 
HRESULT nFooResult = pDispatch.GetPropertyByName(L"Foo", &vFoo); 
CComVariant vBar; 
HRESULT nBarResult = pDispatch.GetProperty(DISPID_BAR, &vBar); 

Классы-упаковщики заботятся о контроле.

+0

Привет, Роман! Спасибо за Ваш ответ. Я знаю об обертках, которые будут работать в приведенном выше примере, описанном выше. К сожалению, я не могу их использовать, так как «реальный код» должен предоставить дополнительные параметры через DISPPARAMS, и я не нашел обертку, которую я могу использовать здесь. – fhw72

1

AddRef() уже был вызван указателем IDispatch. Наиболее типично в коде, который вы не видите, например, метод QueryInterface() сервера. Довольно хорошо скрытый в ATL кстати. Таким образом, указатель интерфейса не может стать недействительным во время вызова, он будет иметь счетчик ссылок по крайней мере 1. Никакой дополнительный AddRef/Release не нужен, чтобы поддерживать его во время вызова Invoke(). Просто убедитесь, что вы вызываете Release(), когда закончите с ним.

Fwiw, вы обычно оставляете это до классов интеллектуального указателя CComPtr или CComQIPtr ATL, они автоматически генерируют вызовы AddRef/Release.

Если вы преследуете утечки памяти, вы будете искать отсутствующие вызовы Release().

+0

Уважаемый Ганс! Большое спасибо. IDispatch * был передан клиенту, поэтому я не уверен, что это уже AddRef'fed в моем случае использования ?! – fhw72