2010-03-04 88 views
5

最近,我花了相当一段时间来编写各种Visual Studio扩展项目。即使项目都是托管代码来访问核心VS服务,仍然需要使用旧式COM接口。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))) 

,你可以看到这个调用返回2个指针(ppHier和PPSC)和对象ppMIS。 现在的问题是:我应该如何去玩与COM引用计数很好。

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

我还假设我得到的是一个对象,它已经被包装到一个RCW中,它将在完成时处理引用释放。

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

为了更改我的问题:假设我使用的COM对象是通过COM规则播放的,上述处理COM引用计数的正确方法的方法是什么?

回答

0

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

当然终结方法可能发生在某个时间不确定性的点,所以如果该对象保持一定的资源,你需要摆脱你应该理想地调用Marshal.ReleaseComObject的包装之前减少它的引用计数为你释放。