【发布时间】:2017-06-26 08:55:04
【问题描述】:
我正在编写一个 .NET 应用程序,我必须在其中使用 API 调用(真的)。我的应用程序通过调用 Win API 的函数CoCreateInstance() 来获取 COM 接口。
当然,我必须在完成这些接口后释放它们。我认为这样做的合适方法是Marshal.Release()(至少,我没有想到其他合理的方法)。
现在,我想让每个相应的接口指针成为一个安全句柄。为此,我必须从SafeHandle 派生我自己的安全句柄类,并且必须在派生类中覆盖ReleaseHandle()。 respective documentation 声明:
[...] 特别是,应用 ReliabilityContractAttribute 属性 从 ReleaseHandle 调用的任何方法。在大多数情况下,此代码 应该是:ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success) [...]
这是我的问题:我不知道Marshal.ReleaseHandle()是否默认已经有这个合约,如果没有,我怎么添加它。我想我在这里缺乏一些基础知识。有没有人能解释一下?
【问题讨论】:
-
Windows API 使用窗口分配方法,内存将根据 Windows 规则而不是 Net Library 规则释放。只有持有内存的 Win API 需要使用 Windows 方法释放。
-
虽然这可能是真的,但我认为它不适用于这里的情况。 COM接口有一种特殊情况。我的问题涉及获取和释放 COM 接口(基本上意味着增加和减少它们的引用计数器),而不是分配或释放内存区域。附带说明一下,如果 COM 对象的所有接口的引用计数器都达到零(但这与我的问题无关),您可能会意识到 COM 对象会自行销毁。
-
只需检查代码就能回答这个问题吗?抽象方法具有属性 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
-
@Will 太好了,你已经准确地回答了我的问题——有时我是个白痴。如果您将评论作为答案,我会接受。我一直在 ReferenceSource 阅读
SafeHandle的实现,但显然没有想到也要阅读Marshal的实现......
标签: c# .net vb.net com safehandle