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;
} %
}
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"], )
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
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