我目前正在使用一个COM服务器(使用ATL)供封闭源VB使用 应用。到目前为止一切正常,但我想确保没有泄漏 那......所以我的问题是:
我是否必须通过以下方式在IDispatch指针上调用AddRef和/或Release:
VARIANT pVar;
IDispatch->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dispparamsNoArgs, &pVar, NULL, NULL);
答案 0 :(得分:3)
如果您的pVar
拥有界面指针(IUnknown*
或IDispatch*
),则表示您已收到AddRef
'。完成后,您有责任进行匹配的发布,通常只需间接清理变体:通过VariantClear
。
该函数通过将vt字段设置为VT_EMPTY来清除VARIANTARG。 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);
包装类负责参考管理。
答案 1 :(得分:1)
已在IDispatch指针上调用AddRef()。最典型的代码是您看不到的,就像服务器的QueryInterface()方法一样。很好地隐藏在ATL顺便说一句。因此,接口指针在调用期间不能变为无效,它的引用计数至少为1.在Invoke()调用期间,不需要额外的AddRef / Release来使其保持活动状态。只需确保在完成后调用Release()。
Fwiw,您通常将其留给ATL的CComPtr或CComQIPtr智能指针类,它们会自动生成AddRef / Release调用。
如果您正在追逐内存泄漏,那么您将寻找缺少的Release()调用。