【问题标题】:Does Marshal.Release() have an implicit ReliabilityContract?Marshal.Release() 是否有隐含的 ReliabilityContract?
【发布时间】: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


【解决方案1】:

抽象方法Marshal.Release的定义是

[System.Security.SecurityCritical]  // auto-generated_required
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk );

所以它已经被 ReliabilityContractAttribute 修饰了。您可以使用反编译器(我使用 JustDecompile)或在referencesource.microsoft.com 上检查任何框架类型的源代码。

【讨论】:

  • 接受答案,尽管您可能想显示Marshal.Release() 的代码(而不是SafeHandle.ReleaseHandle()):-)
  • @Binarus 哈!我转过身来,是的。已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多