Free Wildebeest
Free Wildebeest

Reputation: 7562

Custom destructors in SWIG for opaque structures

I'm unable to work out how to get SWIG to have a custom destructor for an opaque data type that is managed by the library I'm wrapping.

struct Foo;
Foo* NewFoo();
void UpdateFoo(Foo*);
void DestroyFoo(Foo*);

I've attempted to wrap this in SWIG using:

%module lib
%{
#include "lib.h"
%}

%extend Foo {
   ~Foo() {
      DestroyFoo(self);
   }
}
%include "lib.h"

But SWIG warns about Warning 303: %extend defined for an undeclared class Foo. and fails to generate the destructor for Foo in the resulting wrapper C code.

Upvotes: 1

Views: 517

Answers (1)

Free Wildebeest
Free Wildebeest

Reputation: 7562

If you give SWIG a dummy definition of the opaque structure then it no longer treats the class as undeclared. This can be achieved by adding struct Foo{}; to the interface file.

Having done this, it's necessary to also suppress the generation of the default constructor by adding %nodefaultctor Foo.

Finally, now that the lifetime of the returned Foo pointer is managed by the destructor, it's wise to hide the destroy function with %ignore DestroyFoo so that it can't be accidentally called and lead to a double deletion.

%module lib
%{
#include "lib.h"
%}

%nodefaultctor Foo;
%extend Foo {
   ~Foo() {
      DestroyFoo(self);
   }
}
%ignore DestroyFoo

%include "lib.h"

// Get SWIG to treat Foo as a declared class.
struct Foo{};

Upvotes: 4

Related Questions