【问题标题】:Can I stop C++/CLI from adding IDisposable to my ref class?我可以阻止 C++/CLI 将 IDisposable 添加到我的 ref 类吗?
【发布时间】:2014-09-16 09:45:05
【问题描述】:

当您在 ref 类上实现析构函数时,C++/CLI 会为您生成 IDisposable 脚手架。此外,如果您没有实现析构函数,但您的类有一个实现IDisposable 的成员变量,那么IDisposable 将再次在您的类上自动实现。这比在 C# 中处理 IDisposable 的方式非常有用,而且要好得多。

我在实现一个持有msclr::com::ptr(一个包含RCW的智能指针)的引用类时遇到了这种行为。

ref class Test /* : IDisposable added by the compiler */
{
  msclr::com::ptr<IWhatever> _aComObject;
}

我的具体情况中,我的类引用的 COM 对象不会“锁定”一些非托管资源,它实际上只是占用了 CLR 看不到的一些非托管内存。因此,我想通过不实现 IDisposable 类来避免混淆我的 ref 类的用户。相反,我想通过使用 GC API 添加适当的内存压力,让 CLR 知道 COM 对象的存在。

所以,问题是:有没有办法在一个没有实现析构函数但持有一个IDisposable 成员变量的引用类上抑制IDisposable 的实现?

注意:这通常是错误的做法,因为它会阻止该类的用户确定性地处置底层 COM 对象,但考虑到特定情况,暴露 IDisposable 有可能会混淆我的 ref 类的用户,因为确实没有必要 Dispose 有问题的 ref 类。

我想一种选择是在没有析构函数的情况下实现 msclr::com::ptr 的变体。

任何其他禁止自动添加 IDisposable 的方法将不胜感激。谢谢。


回答

_aComObject 声明为 msclr::com::ptr (msclr::com::ptr&lt;IWhatever&gt;^) 的句柄。编译器不会将Test 视为该com ptr 对象的“所有者”,并且不会在删除Test 时将其Dispose。

【问题讨论】:

  • 您打算什么时候对 com 对象调用 release 并消除内存压力 - 这些东西通常都在 dispose 调用中进行管理?
  • @morechili:如果没有以确定性方式显式处理,它会以非确定性方式自动发生(我想当 COM 对象的 RCW 变成垃圾并最终确定时)。跨度>
  • 因此我会说将您的对象保留为 IDisposable 更为正确。让客户选择或不选择确定性行为。它是一次性对象,它正在使用非托管资源。我担心那个人。 c++ 正在执行正确的规则,隐藏它们就是隐藏潜在的问题。
  • @morechilli - 我想我已经足够解释为什么我想做我想做的事了。我期望得到响应(IDisposable 是使用非托管资源时唯一可能做的正确事情),并尝试在问题中处理它。
  • 对该问题+1,只是为了“它非常有用,而且比 C# 中的 IDisposable 处理方式要好得多。”

标签: c++-cli idisposable


【解决方案1】:

我认为答案是为 msclr::com::ptr 持有一个 句柄,而不是“按价值”持有它(仍然将它作为“幕后”的句柄持有, 除了 C++CLI 编译器将其视为一个值 - 当所有者对象被删除 (Disposed) 时“删除”它(调用 Dispose)。

【讨论】:

    【解决方案2】:

    我不确定我是否同意避免 IDispose 实现的理由——但为什么不在你的类中存储一个 IWhatever*。然后编译器不应生成 IDisposable 实现。

    如果您不想要析构函数行为,那么 com::ptr 包装器给您带来什么好处?你总是可以在堆栈上声明一个 com::ptr 并在任何给定的方法中将你的成员指针分配给它,如果你真的需要它。

    【讨论】:

    • 我认为您对 IDisposable 和垃圾收集感到困惑。 msclr::com::ptr 将在 GC 时释放 COM ref,而持有本机 COM 指针不会在没有大量工作的情况下实现该结果(有效地重新实现 RCW)。
    • (或者更准确地说,当RCW不再可达时可以收集它,释放COM引用)
    猜你喜欢
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多