SWIG: Automated C/C++ Scripting Extensions
by David Beazley


Example 1:

// example.i : Sample SWIG interface file
%module example
extern int fact(int);

Example 2:

(a)
use example;
print example::fact(4);
24

(b)
>>> import example
>>> example.fact(4)
24
>>>

(c)
% load ./example.so         
% fact 4                    
24
%


Example 3:

%module stdio
%{
#include <stdio.h>
%}
FILE     *fopen(char *filename, char *mode);
int       fclose(FILE *);
unsigned  fread(void *ptr, unsigned size, unsigned nobj, FILE *);
unsigned  fwrite(void *ptr, unsigned size, unsigned nobj, FILE *);
// Now a few memory allocation functions
void *malloc(unsigned nbytes);
void  free(void *);


Example 4: 
use stdio;
sub filecopy {
    my ($source,$target) = @_;
    my $f1 = stdio::fopen($source,"r");
    my $f2 = stdio::fopen($target,"w");
    my $buffer = stdio::malloc(8192);
    my $nbytes = stdio::fread($buffer,1,8192,$f1);
    while ($nbytes > 0) {
          stdio::fwrite($buffer,1,8192,$f2);
          $nbytes = stdio::fread($buffer,1,8192,$f1);
    }
    stdio::free($buffer);
    stdio::fclose($f1);
   stdio::fclose($f2);
}


Example 5:
print $b,"\n";
voidPtr=SCALAR(0x80b093c)
print $f1,"\n";
FILEPtr=SCALAR(0x80b0b28)
print $f2,"\n";
FILEPtr=SCALAR(0x80b0a98)

Example 6: 
$buffer = stdio::malloc(8192);
stdio::fclose($buffer);
Type error in argument 1 of fclose. Expected FILEPtr. at - line 4.

Example 7: 
class Stack {
  public:
    Stack();
    ~Stack();
    void  push(char *value);
    char *pop();
    int   depth();
};

Example 8:
>>> s = new_Stack()
>>> Stack_push(s,"Dave")
>>> Stack_push(s,"Mark")
>>> Stack_push(s,"Kevin")
>>> Stack_pop(s)
'Kevin'
>>> Stack_depth(s)
2
>>> delete_Stack(s)


Example 9:
>>> s = Stack()
>>> s.push("Dave")
>>> s.push("Mark")
>>> s.push("Kevin")
>>> s.pop()
'Kevin'
>>> s.depth()
2
>>> del s

Example 10:
// Make 'double *vector' accept a list of values
%typemap(python,in) double *vector {
    /* Convert a Python List into an array of values */
    int i,sz;
    sz = PyList_Size($source);
    $target = (double *) malloc(sz*sizeof(double));
    for (i = 0; i < sz; i++) {
         $target[i] = (double) PyFloat_AsDouble(PyList_GetItem($source,i));
    }
}
%typemap(python,freearg) double *vector {
    free($source);  /* clean up to avoid memory leaks */
}
void foo(double *vector);

Example 11:
%except(perl5) {
    try {
          $function    // This gets filled in by the real function call
    } catch (RangeError) {
          croak("Range Error");
    } catch (MemoryError) {
          croak("Out of memory");
    } catch (...) {
          croak("Unknown exception!");
    }
}


Listing One
(a) 
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
extern int fact(int);
XS(_wrap_fact) {
    int  _result;
    int  _arg0;
    dXSARGS ;
    if (items != 1) 
        croak("Usage: fact(int );");
    _arg0 = (int )SvIV(ST(0));
    _result = (int )fact(_arg0);
    ST(0) = sv_newmortal();
    sv_setiv(ST(0),(IV) _result);
    XSRETURN(1);
}
XS(boot_example) {
     dXSARGS;
     char *file = __FILE__;
     newXS("example::fact", _wrap_fact, file);
     ST(0) = &sv_yes;
     XSRETURN(1);
}

(b)
# file : example.pm
package example;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package example;
bootstrap example;
@EXPORT = qw( );
1;


Listing Two
#include "Python.h"
extern int fact(int);
static PyObject *_wrap_fact(PyObject *self, PyObject *args) {
    PyObject * _resultobj;
    int  _result;
    int  _arg0;
    if(!PyArg_ParseTuple(args,"i:fact",&_arg0)) 
        return NULL;
    _result = (int )fact(_arg0);
    _resultobj = Py_BuildValue("i",_result);
    return _resultobj;
}
static PyMethodDef exampleMethods[] = {
     { "fact", _wrap_fact, 1 },
     { NULL, NULL }
};
void initexample() {
    Py_InitModule("example", exampleMethods);
}


Listing Three
#include <tcl.h>
#include <string.h>
#include <stdlib.h>

extern int fact(int );
static int _wrap_fact(ClientData clientData, Tcl_Interp *interp, 
                                             int argc,char *argv[]) {
    int  _result;
    int  _arg0;
    if ((argc < 2) || (argc > 2)) {
        Tcl_SetResult(interp, "Wrong # args. fact { int  } ",TCL_STATIC);
        return TCL_ERROR;
    }
    _arg0 = (int ) atol(argv[1]);
    _result = (int )fact(_arg0);
    sprintf(interp->result,"%ld", (long) _result);
    return TCL_OK;
}
/* Initialization function that gets called upon module loading */
int Example_Init(Tcl_Interp *interp) {
     if (interp == 0) 
         return TCL_ERROR;
     Tcl_CreateCommand(interp, "fact", _wrap_fact, (ClientData) NULL, 
                                             (Tcl_CmdDeleteProc *) NULL);
     return TCL_OK;
}


Listing Four
%module stack
%{
#include "stack.h"
%}
// These functions are inlined into SWIG's output and wrapped
%inline %{
Stack *new_Stack() {
    return new Stack();
}
void delete_Stack(Stack *s) {
    delete s;
}
void Stack_push(Stack *s, char *value) {
    s->push(value);
}
char *Stack_pop(Stack *s) {
    return s->pop();
}
int Stack_depth(Stack *s) {
    return s->depth();
}
%}

Listing Five 
import stack
class Stack :
    def __init__(self):
        self.this = stack.new_Stack()
    def __del__(self):
        stack.delete_Stack(self.this)
    def push(self,arg0):
        stack.Stack_push(self.this,arg0)
    def pop(self):
        return stack.Stack_pop(self.this)
    def depth(self):
        return stack.Stack_depth(self.this)
    def __repr__(self):
        return "<C Stack instance>"



1


