SWIG Python - wrapping a function that expects a double pointer to a struct

pointers, python, swig

Solution

Given the header file:

struct SCIP {};

void SCIPcreate(struct SCIP **s) {
  *s = malloc(sizeof **s);
}

We can wrap this function using:

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

%typemap(in,numinputs=0) struct SCIP **s (struct SCIP *temp) {
  $1 = &temp;
}

%typemap(argout) struct SCIP **s {
  %set_output(SWIG_NewPointerObj(SWIG_as_voidptr(*$1), $*1_descriptor, SWIG_POINTER_OWN));
}

%include "test.h"

which is two typemaps, one to create a local, temporary pointer to be used as the input to the function and another to copy the value of the pointer after the call into the return.

As an alternative to this you could also use `%inline` to set an overload:

%newobject SCIPcreate;
%inline %{
  struct SCIP *SCIPcreate() {
    struct SICP *temp;
    SCIPcreate(&temp);
    return temp;
  }
%}

Problem

I'm wrapping a C library that contains a struct: ``` struct SCIP { //... } ``` and a function that creates such a struct: ``` void SCIPcreate(SCIP** s) ``` SWIG generates a python class `SCIP` and a function `SCIPcreate(*args)` from that. When I now try calling `SCIPcreate()` in python, it obviously expects a parameter of type `SCIP**`, how am I supposed to create such a thing? Or should I try and extend the `SCIP` class with a constructor that calls `SCIPcreate()` automatically? If so, how would I go about that?

Original source