Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to dispose of SWIG-generated objects?

I'm currently using a library built from SWIG into .NET. The documentation for this library doesn't seem to give any information on whether or what of the classes created needs to be disposed. I've also seen discussion on other forums about needing to add code to dispose of child elements that I don't see in the source for this library. On top of all of this, the sample projects and tests for the library do not include usings, nor dispose of the objects they create.

So, for the 'average' SWIG object, do I need to dispose of it? It seems that they all have default destructors which delete the object in the underlying C++. If that's the case, then can I just treat them as any other object and let the garbage collector handle them (barring things that would prevent the garbage collector from handling them properly, like circular references and other classic memory leaks). It'd suck to have to wrap all calls/objects to this library with some kind of disposal context or something.

like image 250
Nate Diamond Avatar asked Oct 30 '22 07:10

Nate Diamond


1 Answers

Given the answers in the comments, it seems that it is overall not necessary in my case. SWIG generated proper finalizers which called the dispose function. It is possible that the dispose function is improperly defined in the SWIG definition, but if this is the case then manually disposing won't help anyway.

Edit: While the initial assertion that disposing of the objects is not necessary, there is a case where it may be useful.

Consider the case where you have a list object exposed through SWIG: List Additionally, you have an 'item' object owned by the list: Item

If you were to do this:

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.

To prevent this from happening, you must prevent list from being finalized/disposed until after all of them items are done being used. This can be done in a few ways:

  • Utilize GC.KeepAlive() at the end of all of the uses of items. E.g.

    item.GetValue();

    GC.KeepAlive(list);

  • Utilize the IDisposable pattern to ensure deterministic disposal of the parent object. E.g.

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

So manual disposal or using the IDisposable pattern is not necessary per se, but it can be useful to make sure that your use of the unmanaged objects is safe, consistent, and clear.

like image 58
Nate Diamond Avatar answered Nov 15 '22 06:11

Nate Diamond