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

Do I need to dispose of SWIG-generated objects?

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

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

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

编辑:虽然最初断言不需要处理对象,但在某些情况下它可能会有用。

考虑您有一个通过 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.

为防止这种情况发生,您必须防止 list 成为 finalized/disposed,直到 所有 item 都完成用过的。这可以通过几种方式完成:

  • 在所有 item 的使用结束时使用 GC.KeepAlive()。例如

    item.GetValue();

    GC.KeepAlive(list);

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

using(List list = new List(1, 2, 3))
{
    Item item = list.Get(1);
    item.GetValue();
}

因此,手动处置或使用 IDisposable 模式本身 不是必需的 ,但它可能有助于确保您对非托管对象的使用是安全的,一致,清晰。