我需要处置 SWIG 生成的对象吗?

Nat*_*ond 5 c# swig idisposable

我目前正在使用从 SWIG 构建到 .NET 中的库。该库的文档似乎没有提供有关是否需要处置所创建的类或需要处置哪些类的任何信息。我还在其他论坛上看到过有关需要添加代码来处理我在该库的源代码中没有看到的子元素的讨论。最重要的是,该库的示例项目和测试不包含usings,也不处理它​​们创建的对象。

那么,对于“普通”SWIG 对象,我需要丢弃它吗?似乎它们都有默认的析构函数,可以删除底层 C++ 中的对象。如果是这种情况,那么我可以将它们视为任何其他对象并让垃圾收集器处理它们(除非阻止垃圾收集器正确处理它们,例如循环引用和其他经典内存泄漏)。如果必须用某种处理上下文或其他东西来包装对该库的所有调用/对象,那就太糟糕了。

Nat*_*ond 2

鉴于评论中的答案,似乎在我的情况下总体上没有必要。SWIG 生成了正确的终结器,它调用了 dispose 函数。SWIG 定义中可能未正确定义 dispose 函数,但如果是这种情况,那么手动 dispose 无论如何都无济于事。

编辑:虽然最初断言没有必要处置对象,但在某些情况下它可能有用。

考虑这样的情况:您有一个通过 SWIG 公开的列表对象:List 此外,您还有一个由列表拥有的“item”对象:Item

如果你要这样做:

List list = new List(1, 2, 3);
Item item = list.Get(1);
// list is now available for garbage collection, as there are no longer any P/invokes nor 
// references to it
item.GetValue(); // Can possibly throw AccessViolationException if list
                 // has been garbage collected based on how it cleans up its items.
Run Code Online (Sandbox Code Playgroud)

为了防止这种情况发生,您必须防止在所有这些都使用完毕之前list被最终确定/处置。这可以通过几种方式来完成:item

  • GC.KeepAlive()在 s 的所有用法的末尾使用item。例如

    item.GetValue();

    GC.KeepAlive(list);

  • 利用该IDisposable模式来确保父对象的确定性处理。例如

using(List list = new List(1, 2, 3))
{
    Item item = list.Get(1);
    item.GetValue();
}
Run Code Online (Sandbox Code Playgroud)

因此,手动处理或使用该IDisposable模式本身并不是必要的,但它对于确保您对非托管对象的使用是安全、一致和清晰的非常有用。