Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 665
PeterE Avatar asked Nov 14 '12 14:11

PeterE


1 Answers

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;
  }
%}
like image 144
Flexo Avatar answered Nov 09 '22 10:11

Flexo