我可以阻止 C++/CLI 将 IDisposable 添加到我的引用类中吗?

发布于 2024-07-13 04:13:38 字数 1167 浏览 7 评论 0原文

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

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

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

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

因此,问题是:是否有一种方法可以抑制在未实现析构函数但包含 IDisposable 成员变量的 ref 类上实现 IDisposable

注意:通常这样做是错误的,因为它会阻止类的用户确定性地处置底层 COM 对象,但在特定情况下,会暴露 IDisposable 有可能使我的引用类的用户感到困惑,因为实际上没有必要处理有问题的引用类。

我想一个选择是实现不带析构函数的 msclr::com::ptr 的变体。

任何其他禁止自动添加 IDisposable 的方法都将受到赞赏。 谢谢。


回答

_aComObject 声明为 msclr::com::ptr 的句柄 (msclr::com::ptr^)。 然后,编译器不会将 Test 视为 comp ptr 对象的“所有者”,并且在删除 Test 时不会释放它。

C++/CLI helpfully generates the IDisposable scaffolding for you when you implement a destructor on a ref class. Also, if you don't implement a destructor, but your class has a member variable which implements IDisposable, then IDisposable is again automatically implemented on your class. It's pretty helpful and much better than how IDisposable is handled in C#.

I have run into this behaviour when implementing a ref class that holds onto an msclr::com::ptr (a smart pointer that contains an RCW).

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

In my specific case, the COM object referenced by my class doesn't 'lock' some unmanaged resource, it effectively just uses up a bit of unmanaged memory that the CLR can't see. Therefore I would like to avoid confusing the users of my ref class by not implementing IDisposable the class. Instead I want to make the CLR aware of the existence of the COM object by using the GC API to add the appropriate memory pressure.

So, the question is: is there a way to suppress implementation of IDisposable on a ref class that doesn't implement a destructor, but does hold an IDisposable member variable?

NB: often this would be the wrong thing to do, as it would prevent users of the class from deterministically disposing of the underlying COM object, but given the particular circumstances, exposing IDisposable has the potential to confuse users of my ref class, since it really is not necessary to Dispose of the ref class in question.

I suppose one option would be to implement a variant of msclr::com::ptr without a destructor.

Any other method to suppress the automatic addition of IDisposable would be appreciated. Thanks.


Answer

Declare _aComObject as a handle to an msclr::com::ptr (msclr::com::ptr<IWhatever>^). The compiler does not then regard Test as being the 'owner' of the com ptr object, and does not Dispose it when Test is deleted.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

默嘫て 2024-07-20 04:13:38

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

I think the answer is to hold a handle to the msclr::com::ptr rather than holding it 'by value' (which is still holding it as a handle 'behind the scenes', except the C++CLI compiler treats it as a value - 'deleting' it (calling Dispose) when the owner object is deleted (Disposed)).

笑叹一世浮沉 2024-07-20 04:13:38

我不确定我是否同意避免 IDispose 实现的理由 - 但为什么不在您的类中存储 IWhatever* 呢? 编译器不应生成 IDisposable 实现。

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

I'm not sure I agree with the ratioanle for avoiding the IDispose implementation -- but why not just store an IWhatever* in your class. The compiler shouldn't then generate the IDisposable implementation.

If you don't want the destructor behaviour then what benefit is the com::ptr wrapper buying you? You can always declare an com::ptr on the stack and assign your member pointer to it in any given method if you really need it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文