swig python - wrapping a function that expects a double pointer to a struct

  • Last Update :
  • Techknowledgy :

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"

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;
   } %
}

Suggestion : 2

A tour of basic C/C++ wrapping Modules Functions Global variables Constants and enums Pointers Structures C++ classes C++ inheritance Pointers, references, values, and arrays C++ overloaded functions C++ operators C++ namespaces C++ templates C++ Smart Pointers C++ Reference Counted Objects (ref/unref) , By default, SWIG tries to build a very natural Python interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping. , Related to containers, ownership issues can arise whenever an object is assigned to a member or global variable. For example, consider this interface: , If this makes you uneasy, rest assured that there is no deep magic involved. Underneath the covers, pointers to C/C++ objects are simply represented as opaque values using an especial python container object:

/* File: example.i */ %
module example

   %
   {
      #define SWIG_FILE_WITH_INIT#include "example.h"

      %
   }

int fact(int n);
/* File: example.c */

#include "example.h"

int fact(int n) {
   if (n < 0) {
      /* This should probably return an error, but this is simpler */
      return 0;
   }
   if (n == 0) {
      return 1;
   } else {
      /* testing for overflow would be a good idea here */
      return n * fact(n - 1);
   }
}
/* File: example.h */

int fact(int n);
$ swig - python example.i
$ swig - c++ - python example.i
#!/usr/bin/env python

""
"
setup.py file
for SWIG example
   ""
"

from distutils.core
import setup, Extension

example_module = Extension('_example',
   sources = ['example_wrap.c', 'example.c'],
)

setup(name = 'example',
   version = '0.1',
   author = "SWIG Docs",
   description = ""
   "Simple swig example from docs"
   "",
   ext_modules = [example_module],
   py_modules = ["example"],
)

Suggestion : 3

In this file, SWIG doesn't know what a FILE is, but since it's used as a pointer, so it doesn't really matter what it is. If you wrapped this module into Python, you can use the functions just like you expect :, When you first wrap something like this into an extension module, you may find the function to be impossible to use. For instance, in Python: , When SWIG creates its output file, it is broken up into four sections corresponding to runtime code, headers, wrapper functions, and module initialization code (in that order). , SWIG tracks typedef declarations and uses this information for run-time type checking. For instance, if you use the above typedef and had the following function declaration:

swig[options] filename
-allegrocl Generate ALLEGROCL wrappers
   -
   chicken Generate CHICKEN wrappers -
   clisp Generate CLISP wrappers -
   cffi Generate CFFI wrappers -
   csharp Generate C # wrappers -
   guile Generate Guile wrappers -
   java Generate Java wrappers -
   lua Generate Lua wrappers -
   modula3 Generate Modula 3 wrappers -
   mzscheme Generate Mzscheme wrappers -
   ocaml Generate Ocaml wrappers -
   perl Generate Perl wrappers -
   php Generate PHP wrappers -
   pike Generate Pike wrappers -
   python Generate Python wrappers -
   r Generate R(aka GNU S) wrappers -
   ruby Generate Ruby wrappers -
   sexp Generate Lisp S - Expressions wrappers -
   tcl Generate Tcl wrappers -
   uffi Generate Common Lisp / UFFI wrappers -
   xml Generate XML wrappers

   -
   c++Enable C++parsing -
   Dsymbol Define a preprocessor symbol -
   Fstandard Display error / warning messages in commonly used format -
   Fmicrosoft Display error / warning messages in Microsoft format -
   help Display all options -
   Idir Add a directory to the file include path -
   lfile Include a SWIG library file. -
   module name Set the name of the SWIG module -
   o outfile Name of output file -
   outcurrentdir Set
default output dir to current dir instead of input file 's path -
   outdir dir Set language specific files output directory -
   swiglib Show location of SWIG library -
   version Show SWIG version number
% module mymodule
   %
   {
      #include "myheader.h"

      %
   }
// Now list ANSI C/C++ declarations
int foo;
int bar(int x);
...
$ swig - c++ - python - o example_wrap.cpp example.i
$ swig - c++ - python - outdir pyfiles - o cppfiles / example_wrap.cpp example.i
cppfiles / example_wrap.cpp
pyfiles / example.py

Suggestion : 4

This pointer can be passed around to functions that expect to receive an int * (just like C).,If you wrap a C structure, it is wrapped by a Python class.,The %array_class(type, name) macro creates wrappers for an unbounded array object that can be passed around as a simple pointer like int * or double *. For instance, you will be able to do this in Python:,Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status.

% {
   extern char * path; %
} %
immutable;
extern char * path; %
mutable;
% {
   extern char * path; %
} %
immutable path;
...
extern char * path; // Read-only (due to %immutable)
#define PI 3.14159
#define VERSION "1.0"

enum Beverage {
   ALE,
   LAGER,
   STOUT,
   PILSNER
};

%
constant int FOO = 42; %
constant
const char * path = "/usr/local";
struct Vector {
   double x, y, z;
};
>>> v = example.Vector() >>>
   v.x = 3.5
>>> c = example.Bar() >>>
   c.x = b.x # Copy contents of b.x to c.x