gpt4 book ai didi

c# - 如何从 C# 中确定性地处理托管 C++/CLI 对象?

转载 作者:可可西里 更新时间:2023-11-01 08:22:13 26 4
gpt4 key购买 nike

我在 C++/CLI 程序集中有一个托管对象。作为 C++/CLI,它通过其“析构函数”实现一次性模式(是的,我知道它与标准 C++ 析构函数不同)。在 C++/CLI 中,我将简单地删除 对象。但是,我将此对象用作 C# 类中的成员变量。

然后,在我的 C# 类中,当我完成使用它时,我想在 C++/CLI 对象上调用等效的 Dispose() 方法。因为它是(而且必须是)类的成员变量,所以使用 using() block 是不可能的。据我所知,除了 C++/CLI 之外,没有公开的方法可以直接、确定性地处理资源。我怎样才能做到这一点?

最佳答案

它在 C++/CLI 中不是那么明显,但它的工作方式完全在 C# 中。当您使用对象浏览器查看类时,您可以看到它。或者像 ildasm.exe 这样的反编译器,这是查看其功能的最佳方式。

当您编写析构函数时,C++/CLI 编译器会自动生成一堆代码。它实现了一次性模式,你的类自动实现了 IDisposable,即使你没有那样声明它。您将获得一个公共(public) Dispose() 方法、一个 protected Dispose(bool) 方法和一个对 GC::SuppressFinalize() 的自动调用。

您在 C++/CLI 中使用 delete 显式调用它,编译器发出 Dispose() 调用。通过使用堆栈语义,您可以在 C++/CLI 中获得与 RAII 等效的功能,编译器会自动在作用域 block 的末尾发出 Dispose 调用。 C++ 程序员熟悉的语法和行为。

如果该类是用 C# 编写的,那么您所做的事情与您在 C# 中所做的完全相同。您调用 Dispose() 以显式调用,您使用 using 语句以异常安全的方式隐式调用它。

相同的规则适用于其他方面,只有当您需要释放非托管内存时才需要析构函数。几乎总是一个 native 对象,即您在构造函数中分配的对象。考虑到如果非托管对象很小并且 GC::AddMemoryPressure() 是一个非常不错的选择,那么可能不值得这么麻烦。但是,您必须在此类包装器类中实现终结器 (!ClassName())。您不能强制外部客户端代码调用 Dispose(),这样做是可选的,而且经常被遗忘。您不希望这样的疏忽导致非托管内存泄漏,终结器确保它仍然被释放。通常编写析构函数最简单的方法是显式调用终结器(this->!ClassName();)

关于c# - 如何从 C# 中确定性地处理托管 C++/CLI 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4935167/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com