COM互操作引用计数指南

mfe*_*old 5 com interop

最近我花了很多时间编写各种Visual Studio Extensions项目.即使项目都是访问核心VS服务的托管代码,仍然需要使用旧式COM接口.

这是一个例子:

var selectionTracker = (IVsMonitorSelection)serviceProvider.GetService(typeof(SVsShellMonitorSelection));
IntPtr ppHier;
uint pitemid;
IVsMultiItemSelect ppMIS;
IntPtr ppSC;
selectionTracker.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC)))
Run Code Online (Sandbox Code Playgroud)

你可以看到这个调用返回2个指针(ppHier和ppSC)和一个对象ppMIS.问题是:我应该如何使用COM引用计数来好好玩它.

我的理解是,在COM世界中,当一个方法返回一个指向对象的指针时,该指针在返回之前是AddRef'ed.这意味着为了防止COM对象泄漏,我必须在使用它们时释放它们.

我还假设我作为一个对象获得了它已经被包装到RCW中,它将在最终确定时负责引用释放.

应用于上述调用的这两个假设意味着我必须确保在我的2个指针上调用`Marshal.Release',但是对于返回的对象,我不应该对引用计数做任何事情.

重新解释一下我的问题:假设我使用的COM对象是按COM规则播放的,那么处理COM引用计数的方法是否正确?

tyr*_*nid 0

在这种特殊情况下,您需要对IntPtr变量调用Marshal.Release,否则它们将不会消失。当然,如果你告诉编组器直接使用对象(或特定类型),那么你就不需要担心它,因为 RCW 将确保该对象在将来的某个时刻被销毁(即,当调用终结器时)垃圾收集过程)。

当然,终结器方法可能发生在不确定的时间点,因此如果对象维护了一些您需要删除的资源,您最好在包装器为您释放之前调用Marshal.ReleaseComObject来减少其引用计数。