2

我目前正在开发一个供闭源 VB 应用程序使用的 COM 服务器(使用 ATL)。到目前为止一切正常,但我想确保没有泄漏......所以我的问题是:

我是否必须在通过以下方式获得的 IDispatch 指针上调用 AddRef 和/或 Release:

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

2 回答 2

4

如果你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);

包装类负责引用管理。

于 2013-06-13T14:53:24.653 回答
1

AddRef() 已在 IDispatch 指针上调用。最常见的是您看不到的代码,例如服务器的 QueryInterface() 方法。顺便说一句,很好地隐藏在 ATL 中。因此接口指针在调用期间不能变为无效,它的引用计数至少为 1。在 Invoke() 调用期间不需要额外的 AddRef/Release 来使其保持活动状态。只要确保在完成后调用 Release() 即可。

Fwiw,您通常将其留给 ATL 的 CComPtr 或 CComQIPtr 智能指针类,它们会自动生成 AddRef/Release 调用。

如果您正在寻找内存泄漏,那么您将寻找丢失的 Release() 调用。

于 2013-06-13T16:02:53.580 回答