COM互操作引用计数指南

5

最近我花了很多时间编写各种Visual Studio扩展项目。尽管这些项目都是托管代码来访问核心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。这意味着为了防止COM对象泄漏,我必须在使用完它们后释放它们。
我还假设我得到的对象已经包装成了一个RCW,当它被终结时会自动处理引用计数释放。
以上两个假设应用于上述调用意味着,我必须确保在我的两个指针上调用“Marshal.Release”,但对于返回的对象不需要进行任何关于引用计数的操作。
换句话说,假设我使用的COM对象遵循COM规则,那么上述方法是否是处理COM引用计数的正确方式?
1个回答

0
在这种特定的情况下,您需要在IntPtr变量上调用Marshal.Release,否则它们将不会消失。当然,如果您告诉编组器直接使用对象(或特定类型),那么您就不需要担心它,因为RCW将确保在未来某个时刻销毁对象(即在垃圾收集过程中调用终结器时)。
当然,终结器方法可能会在非确定性时间点发生,因此如果对象保留了您需要摆脱的某些资源,则最好在包装程序执行释放操作之前调用Marshal.ReleaseComObject以减少其引用计数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接