我目前正在一个COM服务器上工作(使用ATL)由闭源VB使用应用程序。到目前为止,一切正常,但我想确保没有泄漏在那里……所以我的问题是:
我必须调用AddRef和/或释放一个IDispatch指针通过:
VARIANT pVar;
IDispatch->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dispparamsNoArgs, &pVar, NULL, NULL);
如果你的pVar
持有一个接口指针(IUnknown*
或IDispatch*
),你已经收到它AddRef
'fed。当你完成时,你有责任做一个匹配的发布,你通常只是间接地做清理变体:通过VariantClear
。
顺便说一下,在ATL中不需要使用Invoke来读取属性。你有很好的帮手:该函数通过将vt字段设置为VT_EMPTY来清除VARIANTARG。首先发布VARIANTARG的当前内容。[…如果vtfield为VT_DISPATCH,则释放该对象。[…]
CComPtr<IDispatch> pDispatch;
CComVariant vFoo;
HRESULT nFooResult = pDispatch.GetPropertyByName(L"Foo", &vFoo);
CComVariant vBar;
HRESULT nBarResult = pDispatch.GetProperty(DISPID_BAR, &vBar);
包装器类负责引用管理。
AddRef()已经在IDispatch指针上被调用。最典型的是在看不到的代码中,比如服务器的QueryInterface()方法。顺便说一句,很好地隐藏在ATL中。因此接口指针在调用期间不会失效,它的引用计数至少为1。在Invoke()调用期间,不需要额外的AddRef/Release来保持它的活动状态。只要确保在使用完Release()后调用Release()就可以了。
通常,你把这个问题留给ATL的CComPtr或CComQIPtr智能指针类,它们会自动生成AddRef/Release调用。
如果你正在追逐内存泄漏,那么你会寻找丢失的Release()调用。