最近我花了很多时间编写各种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)))
你可以看到这个调用返回2个指针(ppHier和ppSC)和一个对象ppMIS。 问题是:我应该如何使用COM引用计数来发挥它。
据我所知,在COM世界中,当一个方法返回指向对象的指针时,该指针在返回之前是AddRef'ed。这意味着为了防止COM对象泄漏,我必须在使用它们时释放它们。
我还假设我作为一个对象获得了它已经被包装到一个RCW中,它将在最终确定时负责引用释放。
这两个假设适用于上面的调用意味着我必须确保在我的2个指针上调用`Marshal.Release',但是对于返回的对象,我不应该对引用计数做任何事情。
重新解释一下我的问题:假设我使用的COM对象是按COM规则播放的,那么处理COM引用计数的方法是否正确?
答案 0 :(得分:0)
在这种特殊情况下,您需要在 IntPtr 变量上调用 Marshal.Release ,否则它们不会消失。当然如果你告诉编组人员直接使用对象(或特定类型)那么你就不必担心它,因为RCW将确保在将来的某个时刻销毁对象(即当调用终结器时)垃圾收集过程)。
当然终结器方法可能发生在非确定性的时间点,所以如果对象保留了一些你需要摆脱的资源,理想情况下应该调用 Marshal.ReleaseComObject 来减少它的引用在包装器为您释放之前计数。