.net - .NET 运行时何时保持 COM 对象的引用计数 > 1?

标签 .net com com-interop rcw

直到最近,我还相信 .NET 运行时在创建 runtime-callable wrapper 时只会将 COM 对象的引用计数增加 1。 ,并且为任何给定的 COM 对象只创建一个这样的运行时可调用包装器。

如果我没记错的话,上面的意思是 Marshal.FinalReleaseComObjectMarshal.ReleaseComObject在实践中做同样的事情。

但是,今天我正在编写一些测试来验证我的代码是否正确释放了 COM 对象。我通过调用应该释放的对象并检查预期的 InvalidComObjectException 来做到这一点。 . 事实证明,在某些情况下会在 FinalReleaseComObject 之后引发异常。 ,但不是在 ReleaseComObject 之后.

这是否意味着 .NET 2.0 运行时可以保存多个对 COM 对象的引用?如果是这样,它什么时候这样做?

最佳答案

这里有一个额外的间接级别。是的,RCW 在 native COM 接口(interface)指针上保留一个引用计数。但是 RCW 也有一个引用计数,每次 COM 接口(interface)指针映射到 RCW 时它都会增加。如果 COM 方法返回接口(interface)指针,可能会发生这种情况。相应的 .NET 包装类的终结器会递减它。

您可以直接通过 Marshal.ReleaseComObject() 修改该引用计数,它像终结器一样将其减一,而 Marshal.FinalReleaseComObject() 将其归零,保证调用 IUnknown::Release() 方法.他们当然属于“更好地知道你在做什么”类别。弄错会产生丑陋且无法调试的“COM 对象与其底层 RCW 分离”异常。

关于.net - .NET 运行时何时保持 COM 对象的引用计数 > 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2567236/

相关文章:

c# - 使用 COM 二进制序列化作为 C# 和 C++ 不可抗拒的格式

c++ - 使用 MinGW 构建 ActiveQt (COM) 应用程序

c# - 互操作类作为泛型类型参数有什么问题?

c# - 带有数据网格和 TabControl 的 WPF MVVM Master 详细信息 View

c# - .NET - 我目前运行的是什么版本的框架(来自 C#)

.net - 上下文自然语言资源,我从哪里开始?

c# - 使用out参数的优缺点是什么

c# - 如何在 C# 中实例化 IDispatchEx?

c# - C# 结构的属性在 COM 和 VB6 中获得不可用的名称?

c# - 如何创建 SafeArray C#?