SWIG1.3a5 Typemap FAQ for Python, Perl5(,Tcl)

This is my collection of SWIG typemap FAQ for Python and Perl5. Tcl portion will be provided later. The SWIG version is based on 1.3a5. All credits should go to the authors in SWIG mailing list. Direct any of your question about this FAQ to pinhong@eecs.berkeley.edu. [Last update on 06/06, 2001]

  1. Standard typemaps for int, short, long, char* and FILE*.
  2. Wrapping a non-object C code into an object class in SWIG.
  3. Passing NULL from Perl/Tcl/Python to a C/C++ function.
  4. char ** in/out typemaps.
  5. int array in a structure field
  6. C++ string in/out typemap.
  7. Return string bug in Python interface.
  8. Using C++ streams.
  9. Making void* compatible with other data types.
  10. void* in/out typemaps.
  11. Pointer overcasting.
  12. Wrapping a C++ sequence class for Python.
  13. Including code into Python/Perl shadow class.
  14. Overriding Python/Perl default class method (generated by SWIG -shadow).
  15. Wrapping a C++ class with overloaded methods.
  16. Wrapping a C++ class with an overloaded constructor.
  17. Enforcing the order in which variables are converted from scripting types to C types.
  18. Typemaps for fixed length buffer.
  19. Implicit size typemap of an input array.
  20. Input typemap for array(or STL vector) of pointers.
  21. Pointer typecasting in an output list or STL vector.
  22. Generic pointer argout typemap.
  23. Argument out typemaps for pre-allocated buffer.
  24. Argument out typemaps for a C++ reference to a pointer.
  25. Argument out typemaps for C++ reference.
  26. Generic argout typemaps for objects/Difference in argout typemaps.
  27. Object pointer does not get shadowed.
  28. Object typecasting in an output list or STL vector.
  29. Generic shadow object typecasting in C/C++.
  30. Wrapping a function prototype like foo(int argc, char **argv).
  31. Operator overloading support.
  32. Wrapping "friend ostream& operator<<" in Python
  33. Reducing Perl shadowing scheme overhead.
  34. Detecting dependency between header files
  35. C++ complains about incompatible types in assignment of char[] for a struct field set function.
  36. Structure marshaling code/typemap.
  37. Automatic callback generation.
  38. Case study for Perl5, Tcl8 and Python comparison.
  39. 2-D argout typemaps.
  40. C preprocessor directive pass-through.
  41. Makefile generation for SWIG compilation.

1. Standard typemaps for int, short, long, char* and FILE*.
[Detail] I need to copy and paste some standard typemaps. Where I can find them?

[Answer] Basically, you can check it out from SWIG user guide. Here are some of them:
[Python]

Python -> C/C++, %typemap(python,in)
char *
%typemap(python,in) char * {
   if (!PyString_Check($source)) {
      PyErr_SetString(PyExc_TypeError,not a string);
      return NULL;
   }
   $target = PyString_AsString($source);
}
int,
short,
long
%typemap(python,in) int,short,long {
   if (!PyInt_Check($source)) {
      PyErr_SetString(PyExc_TypeError,"not an integer);
      return NULL;
   }
   $target = ($type) PyInt_AsLong($source);
}
float,
double
%typemap(python,in) float,double {
   if (!PyFloat_Check($source)) {
      PyErr_SetString(PyExc_TypeError,not a float);
      return NULL;
   }
   $target = ($type) PyFloat_AsDouble($source);
}
FILE *
%typemap(python,in) FILE * {
   if (!PyFile_Check($source)) {
      PyErr_SetString(PyExc_TypeError,not a file);
      return NULL;
   }
   $target = PyFile_AsFile($source);
}


C/C++ -> Python, %typemap(python,out)
char *
%typemap(python,out) char *,const char *{
   $target = Py_BuildValue("s", ($type) $source);
}
or
%typemap(python,out) char *,const char *{
   $target=Py_BuildValue("s#",($type)$source,length);
}
int, short
%typemap(python,out) int, short {
   $target = Py_BuildValue("i", ($type) $source);
}
long
%typemap(python,out) long {
   $target = Py_BuildValue("l", ($type) $source);
}
float, double
%typemap(python,out) float, double {
   $target = PyBuild_Value("d",($type) $source);
}
FILE *
%typemap(python,out) FILE * {
   $target = PyFile_FromFile($source);
}


[Perl5]

Perl -> C/C++, %typemap(perl5,in)
char *
%typemap(perl5,in) char * {
   $target = SvPV($source,PL_na);
}
or
%typemap(perl5,in) char * {
   $target = SvPV($source,length);
}
int, short, long
%typemap(perl5,in) int,short,long {
   $target = ($type) SvIV($source);
}
double
%typemap(perl5,in) float, double {
   $target = ($type) SvNV($source);
}
FILE *
%typemap(perl5,in) FILE * {
   $target = IoIFP(sv_2io($source));
}


C/C++ -> Perl, %typemap(perl5,out)
char *
%typemap(perl5,out) char * {
   $target = sv_newmortal();
   sv_setpv($target,$source);
   //sv_setpvn($target,$source,length);
   argvi++;
}
int, short, long
%typemap(perl5,out) int,short,long {
   $target = sv_newmortal();
   sv_setiv($target,(IV) $source);
   argvi++;
}
float,double
%typemap(perl5,out) float, double {
   $target = sv_newmortal();
   sv_setiv($target,(double) $source);
   argvi++;
}


2. Wrapping a non-object C code into an object class in SWIG.
[Detail] I have a C library which has an opaque type, and several "methods". For example:
typedef internal_foo_struct foo;
foo *foo_new(void);
void foo_destroy(foo *f);
int foo_connect(foo *f);
int foo_do_something(foo *f, int n);
int foo_disconnect(foo *f);
I would like to map this into an object in the swig-output languages.

[Answer] Define it in the SWIG interface file like this:

class foo {
public:
    %addmethods {
        foo() {
            return foo_new();
        }
        ~foo() {
            foo_destroy(self);
        }
        int connect() {
            return foo_connect(self);
        }
        int do_something(int n) {
            return foo_do_something(self, n);
        }
        // etc...
    }
};
Be sure to use the -c++ flag when invoking swig. If you have a constructor like
 
foo *new_foo(int n);
You don't need to wrap it with another shell, so the addmethods should be:
%addmethods foo{
      foo(int n);
}


3. Passing NULL from Perl/Tcl/Python to a C/C++ function.
[Detail] How I could pass a NULL value to my C/C++ function? Something like this:
tw_createDialogue(20,20, 2,2, 0, "NULL", "NULL");

[Answer]Use the following language element to represent NULL:



4. char ** in/out typemaps.
[Detail] How can I get a list of strings instead of '_p_p_char' in SWIG?

[Answer] The following code is from SWIG1.1p5 examples.

%typemap(python,in) char ** {
  /* Check if is a list */
  if (PyList_Check($source)) {
    int size = PyList_Size($source);
    int i = 0;
    $target = (char **) malloc((size+1)*sizeof(char *));
    for (i = 0; i < size; i++) {
      PyObject *o = PyList_GetItem($source,i);
      if (PyString_Check(o))
        $target[i] = PyString_AsString(PyList_GetItem($source,i));
      else {
        PyErr_SetString(PyExc_TypeError,"list must contain strings");
        free($target);
        return NULL;
      }
    }
    $target[i] = 0;
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}
%typemap(python,freearg) char ** {
  free((char *) $source);
}
%typemap(python,out) char ** {
  int len,i;
  len = 0;
  while ($source[len]) len++;
  $target = PyList_New(len);
  for (i = 0; i < len; i++) {
    PyList_SetItem($target,i,PyString_FromString($source[i]));
  }
}

[Perl]

%typemap(perl5,in) char ** {
	AV *tempav;
	I32 len;
	int i;
	SV  **tv;

	if (!SvROK($source))
	    croak("$source is not an array.");
        if (SvTYPE(SvRV($source)) != SVt_PVAV)
	    croak("$source is not an array.");
        tempav = (AV*)SvRV($source);
	len = av_len(tempav);
	$target = (char **) malloc((len+2)*sizeof(char *));
	for (i = 0; i <= len; i++) {
	    tv = av_fetch(tempav, i, 0);	
	    $target[i] = (char *) SvPV(*tv,PL_na);
        }
	$target[i] = 0;
};

// This cleans up our char ** array after the function call
%typemap(perl5,freearg) char ** {
	free($source);
}

// Creates a new Perl array and places a char ** into it
%typemap(perl5,out) char ** {
	AV *myav;
	SV **svs;
	int i = 0,len = 0;
	/* Figure out how many elements we have */
	while ($source[len])
	   len++;
	svs = (SV **) malloc(len*sizeof(SV *));
	for (i = 0; i < len ; i++) {
	    svs[i] = sv_newmortal();
	    sv_setpv((SV*)svs[i],$source[i]);
	};
	myav =	av_make(len,svs);
	for (i = 0; i < len; i++) {
	  /*	  SvREFCNT_dec(svs[i]); */
	}
	free(svs);
        $target = newRV_noinc((SV*)myav);
        sv_2mortal($target);
	argvi++;                      /* This is critical! */
}
If you don't want a reference array, try this:
%typemap(perl5,out) char ** {
        int i = 0;
        while ($source[i]) {
           if(i+1>items){ EXTEND(sp,1);}
           ST(argvi+i) = sv_newmortal();
           sv_setpv((SV *)ST(argvi+i),$source[i]);
           i++;
        }
        argvi+=i;
}


5. int array in a structure field
[Detail] The problem I have is something like this:
typedef struct
        {
        unsigned int Offset;
        int Range;
        int Pattern[12];
        } TriggerStructure;
There are many structures like these in this API. The problem is the array of integers (or longs, or unsigned, etc.) As you know, SWIG just makes read-only accessors for these. I've read through the documentation, but there is very little about this, in spite of being "common occurence".

What I would like to do from the Python side is this:

ts = TriggerStructure()
ts.Pattern = [1, 2, 45, 54, 7, 8, 6, 7, 1, 10, 11, 12]
But the wrapper code always seems to generate a SWIG pointer object to it

[Answer] SWIG1.3a5 generates before the memberin typemap a pointer conversion call, which checks the input for correct data type and limits the way you can write typemaps, for example,

if ((SWIG_ConvertPtr(argo1,(void **) &arg1,SWIGTYPE_p_int,1)) == -1)
   return NULL;
Actually, $source in the typemap should be "argo1" for flexibility instead of "arg1". Here is a Perl script to comment out this pointer conversion.
#!/usr/bin/env perl -i.bak
while(<>){
   if(/"OO:(\w+?)_(\w+?)_(set|get)"/o){
      print;
      $_ = <>;
      print;
      $conv=<>;
      $_=<>;
      if(/^\s*\{\s*$/o){
         print "/* $conv*/\n";
      }else{
         print $conv;
      }
   }
   print;
}
Now, you can write a pair of typemaps:
%typemap(python, memberin) int [ANY]{
    // source should be argo1
    if (PyList_Check(argo1)) {
       int size = PyList_Size(argo1);
       int i = 0;
       for(i=0;i<size;i++){
          PyObject *o = PyList_GetItem(argo1,i);
          if (PyInt_Check(o)){
             $target[i] = (int)PyInt_AsLong(o);
          }else{
             PyErr_SetString(PyExc_TypeError,"List must contain integers");
             return NULL;
          }
       }
       for(i=size;i<$dim0;i++) $target[i]=0;
    }
}
%typemap(python, out) int* TriggerStructure_Pattern_get{
  int len,i;
  len = 12;
  $target = PyList_New(len);
  for (i = 0; i < len; i++) {
    PyList_SetItem($target,i,PyInt_FromLong((long)$source[i]));
  }
}
They should serve what you need. Remember to run the Perl script above on the SWIG output '*_wrap.c' to comment out the redundant pointer conversion. If you would like to access the individual elements in Pattern, say, for example,
ts = TriggerStructure()
ts.Pattern = [1, 2, 45, 54, 7, 8, 6, 7, 1, 10, 11, 12]
ts.Pattern[2]=22
print ts.Pattern[11]
You can do the following:
%inline %{
   struct TSPattern{
      int *trig;
      int __getitem__(int i){
         if(i>12){
            PyErr_SetString(PyExc_IndexError,"Index is out of range");
            return 0;
         }
         return trig[i];
      }
      void __setitem__(int i,int x){
         if(i>12){
            PyErr_SetString(PyExc_IndexError,"Index is out of range");
            return;
         }
         trig[i]=x;
      }
   };
%}

%typemap(python, memberin) TSPattern *{
    // source should be argo1
    int *tgt=(int*)$target;
    if (PyList_Check(argo1)) {
       int size = PyList_Size(argo1);
       int i = 0;
       for(i=0;i<size;i++){
          PyObject *o = PyList_GetItem(argo1,i);
          if (PyInt_Check(o)){
             tgt[i] = (int)PyInt_AsLong(o);
          }else{
             PyErr_SetString(PyExc_TypeError,"List must contain integers");
             return NULL;
          }
       }
       for(i=size;i<12;i++) tgt[i]=0;
    }
}

%typemap(python, out) TSPattern *{
   static TSPattern t;
   t.trig=(int*)$source;
   $target=SWIG_NewPointerObj((void *)&t, SWIGTYPE_p_TSPattern);
}
typedef struct
        {
        unsigned int Offset;
        int Range;
        TSPattern *Pattern; // Note a type change here
        } TriggerStructure;

%{  typedef struct {...} TriggerStructure; ...%}
We are using the techniques in SWIG1.1 User manual chap. 9. The drawback for the code above is too much "dimension" hard coding.

[Perl5] For perl, suppose we have a C struct like:

typedef struct _myStruct {
        ...
        int myIntArray[4];
} myStruct 
Use the following pair of typemaps:
%typemap(perl5,out) int* myStruct_myIntArray_get{
  AV *myav;
  SV **svs;
  if ($source) {
    svs = (SV **) malloc(4*sizeof(SV *));
    svs[0] = sv_newmortal();
    sv_setiv((SV*) svs[0],$source[0]);
    svs[1] = sv_newmortal();
    sv_setiv((SV*) svs[1],$source[1]);
    svs[2] = sv_newmortal();
    sv_setiv((SV*) svs[2],$source[2]);
    svs[3] = sv_newmortal();
    sv_setiv((SV*) svs[3],$source[3]);
    myav = av_make(4,svs);
    free(svs);
    $target = newRV_noinc((SV*)myav);
    sv_2mortal($target);
    argvi++;
   }
}

%typemap(perl5,memberin) int myIntArray[ANY]{
   AV *tempav;
   int i;
   SV  **tv;
   /* NOTE source = ST(1) */
   if (!SvROK(ST(1)))
       croak("input is not an array.");
   if (SvTYPE(SvRV(ST(1))) != SVt_PVAV)
       croak("input is not an array.");
   tempav = (AV*)SvRV(ST(1));
   for (i = 0; i < $dim0; i++) {
       tv = av_fetch(tempav, i, 0);
       $target[i] = (int) SvIV(*tv);
   }
}
And, unfortunately, you need to modify "myModule_wrap.c" using the following script to remove SWIG type check.
#!/usr/bin/env perl -i.bak
# mark_pl_tcheck.pl
$field=shift @ARGV;
while(<>){
   if(/^\s*XS.+?${field}_set/o){
      print;
      while(<>){
         if(/SWIG_ConvertPtr\(ST\(1\)/o){
            while(<>){ last if /^\s*\}/;}
            last;
         }
         print;
      }
      next;
   }
   print;
}
Run this under unix:
unix> perl mark_pl_tcheck.pl myIntArray myModule_wrap.c
Make and compile your *.c, and you can test it by
   $myStructPtr = getMyStructPtr();
   $myStructPtr->{myIntArray} = [ 1, 2, 3, 4]; # <-- not (1,2,3,4)!
   print $myStructPtr->{myIntArray}[2];
Note that
$myStructPtr->{myIntArray}[2]=99; # Any number
does NOT work. That is to say, the individual element can not be left-hand-side. It is possible to make it work. It is just tricky.

6. C++ string in/out typemap.
[Detail] Using string class in my function input parameter.
const emt_parameters *GetParameters(string element); 

[Answer] You always have to check how the string will be processed. If the C/C++ call will acquire(own) this string, you have to use the following code.

%typemap(python,in) string *, string&, string {
   if (PyString_Check($source)) {
      $target = new string(PyString_AsString($source),
         PyString_Size($source));
   }else{
      PyErr_SetString(PyExc_TypeError,"not a string type");
      return NULL; 
   }
}
%typemap(perl5,in) string *, string&, string {
    $target=new string((char*)SvPV($source, PL_na));
}
// if the C/C++ does not acquire the string, you have to
// add this freearg typemap. 
%typemap(python, freearg) string*, string&, string {
     delete $source;
}
%typemap(perl5, freearg) string*, string&, string {
     delete $source;
}
If you are sure the C/C++ function won't acquire this string, you may do the following to avoid memory allocation(by "new"):
%typemap(python,in) string*, string&, string{
   if (PyString_Check($source)) {
      static string tmp_string(NULL,0);
      tmp_string=string(PyString_AsString($source),
                  PyString_Size($source));
      $target=&tmp_string;
   }else{
      PyErr_SetString(PyExc_TypeError,"not a string type");
      return NULL; 
   }
}
%typemap(perl5,in) string*, string&, string{
   static string tmp_string(NULL,0);
   tmp_string=string((char*)SvPV($source, PL_na));
   $target=&tmp_string; 
}
String out typemaps are simpler:
%typemap(python,out) string*, string&{
     $target = Py_BuildValue("s#",$source->c_str(),$source->size());
}
%typemap(python,out) string {
   $target = Py_BuildValue("s#",$source->c_str(),$source->size());
   delete $source;
}
%typemap(perl5,out) string*, string&{
   sv_setpv($target,$source->c_str());
}
%typemap(perl5,out) string {
   sv_setpv($target,$source->c_str());
   delete $source;
}


7. Return string bug in Python interface.
[Detail] Try the following code with swig -python
 
  %module example
  %inline %{
  char *ret_null(){
     return (char*)NULL;
  }
  %}
I got a core dump.

[Answer] Using this typemap, it should be OK

 
  %typemap(python,out) char *{
     $target=Py_BuildValue("s",$source);
  }


8. Using C++ streams.
[Detail] Many of the C++ methods take streams as parameters. For example:
bool Read(istream & infile);
bool Write(ostream & ofile);
Every attempt to use these functions has generated the same error:
TypeError: Type error. Expected _p_istream

[Answer] The trick is to make SWIG believe ifstream is derived from istream. You don't need to say anything in real C++ code. Try this:

%module istream
%{
#include <iostream.h>
#include <fstream.h>
%}
class istream{ };
class ifstream:public istream{
public:
   ifstream(const char *fn);
   ~ifstream();
};
Test it:
from istream import *
ifs=ifstream("test.txt")
Read(ifs)


9. Making void* compatible with other data types.
[Detail] I have some complex structures in my applications, and in several cases we pass 'void *' instead of the actual pointer type (or vise-versa). since swig requires strict pointer-type matching, I was looking for a way of casting pointer with swig. I know I could create a bunch of helper functions to do this, but that is pretty messy.

[Answer] If you allow to modify your_module_wrap.c, you can use the following perl script:

#!/usr/bin/perl
$fromType=shift @ARGV;
$toType=shift @ARGV;
while(<>){
   if(/^static\s+swig_type_info\s+_swigt__p_$toType\[\]/o){
      print << "END";
static void *_p_${fromType}To_p_${toType}(void *x) {
    return (void *)(($toType *) (($fromType *) x));
}
END
      
s/("$toType\s*\*"\}),/$1,{"_p_$fromType",_p_${fromType}To_p_${toType}},/o;
   }
   print;
}
Use the following command to make Foo compatiable with void.
perl type_conv.pl void Foo your_module_wrap.c > new_wrap.c
What it does is to insert a type conversion record in SWIG type checking system to avoid the problem you got.


10. void* in/out typemaps.
[Detail] When using void* as input/output data type, any typemaps are needed?

[Answer] Actually, you don't need any typemap for void* in typemap. SWIG does not perform type checking in this case.

When using 'void*' as output, you have to overcast it by the data type you need. Check this FAQ.


11. Pointer overcasting.
[Detail] How can I overcast a pointer into another one?

[Answer] Use the following code:
[Python]

def ptrcast(t,ptr):
   import re
   if type(t)!=type(""):
      if len(t.__bases__)==1:
         t=t.__bases__[0].__name__
      else: t=t.__name__
   if hasattr(ptr,"this"):
      ptr=ptr.this
   return re.sub(r"(_p)+_\w+$","_p_"+t,ptr)
Say, for example, if you got a pointer '_101d68_p_Foo', you can over cast it by:
a_Bar_ptr=ptrcast(Bar,'_101d68_p_Foo')
For shadow object, you can do this:
a_Bar_obj=BarPtr(ptrcast(Bar,'_101d68_p_Foo'))

[Perl5]

bless $ptr,"NewClass";
If you are using a shadow object, you need to do
bless $ptr,"NewClass";
bless tied{%{$ptr}},"NewClass";


12. Wrapping a C++ sequence class for Python.
[Detail] I'm using %addmethods to map a C++ interface to the Python sequence interface, i.e., to give it __len__, __getitem__, and __setitem__ methods. They all work as expected on their own. However, when I write
 >>> v = myVector()
 >>> # fill v with some values
 >>> w = map(lambda x:x+1, v)
the last instruction does NOT work as expected, viz., map() does not detect the end of my container and goes into an endless loop.

[Answer] You can raise an IndexError when the container is accessed out of range. Usually, you can write such code:

class MySeq{
    int _len;
    AnItem *arr;
public:
...
%addmethods {
    int __len__(){ return _len;}
    AnItem* __getitem__(int i){ 
       if (i < 0 || i >= _len) {
          PyErr_SetString(PyExc_IndexError, "array index out of range");
          return NULL;
       }
       return arr[i];
    }
    void __setitem__(int i, AnItem *p){ arr[i]=p;}
}
};
There is a more elegant way to do this. You can find it in SWIG User Guide Chapter 9. A more extensive example can be found here


13. Including code into Python/Perl shadow class.
[Detail] Is there a handy way to include block of Python code into shadow classes similar to how blocks of C code can be added to C wrapper files?

[Answer]

%pragma(python) code="python source code"
Adds "python source code" near the begining of the .py file.
  
%pragma(python) include="filename"
Adds the contents of filename to the end of the .py file. It is done similary for Perl.
%pragma(perl5) code="perl source code"
%pragma(perl5) include="filename"
Note that SWIG can include additional code only before the code SWIG generated in '*.pm'. If you need to insert it at the end, you need to explicitly concatenate the additional code to your '*.pm'.

  
%pragma(python) addtomethod="methodName:python source code"
Adds "python source code" to the end of the method named "methodName" in the current class definition. The quoted text can span multiple lines, but you have to make sure you get the indentation right.
%pragma(python) addtoclass="python source code"
Adds "python source code" to the end of the class definition for the current class. The quoted text can span multiple lines, but you have to make sure you get the indentation right. The first two pragmas have been in SWIG for a long time. The last two were submitted by me and David added them in one of the post 1.1p5 releases, so you can use them if you are still using the final 1.1-883 release. I havn't checked yet if they still work in 1.3aX...


14. Overriding Python/Perl default class method (generated by SWIG -shadow).
[Detail] I'd like to have a different C++ destructor in __del__ method.

[Answer] You can write your own destructor in C++, and make Python call __del__ with a different class method.

%pragma(python) include="new__del__.py"
And in "new__del__.py", you should have
class Foo(Foo):
...
def __del__(self,myClassc=myClassc):
   if self.thisown == 1 :
      myClassc.my_delete_Foo(self)


15. Wrapping a C++ class with overloaded methods.
[Detail] For instance,
//file truc.h
class truc
{...
        void mymethod(int, int);
        void mymethod(float);
}
SWIG will give an error like this:
Line 17. Function truc_mymethod (member mymethod) multiply defined (2nd definition ignored).

[Answer] You need to specify a different name for them to be used in Python. For example,

class truc
{...
%name(mymethod_int) void mymethod(int, int);
%name(mymethod_float) void mymethod(float);
}           

%pragma(python) include="truc_overloaded.py"
In truc_overloaded.py, you specify this:
class truc(truc):
   def mythod(self,*args):
      if len(args)==2:
         val=apply(trucc.mymethod_int,args)
      else:
         val=apply(trucc.mymethod_float,args)
      return val
Here is a Perl script that automatically does this for you if your overloaded interfaces are different only in the number of arguments:
#!/usr/bin/env perl
$ifile=shift @ARGV;
open(F,"swig -python -shadow -c++ $ifile 2>&1 |");
$errCount=0;
while(<F>){
   if(/multiply defined /o){
      /Line (\d+)\s*\.\s*(\w+)\s+(\S+)/o;
      $n=$1;
      $md{$n}=[$2,$3,0];
      if(/\(member /o){
         $md{$n}[2]=1;
      }
   }
}
close(F);
open(IFILE,$ifile);
unshift @line,"";
while(<IFILE>){
   #$line[$num]="%name(${name}__L$num) ".$line[$num];
   if(/%module\s+(\S+)/o){ $mod=$1;}
   if(/class\s+(\w+)/o){ $class=$1;}
   if(exists $md{$.}){
      $s=$_;
      if($_ !~ /\)\s*;/o && $_ =~ /\)\s*\{/o){
         while(<IFILE>){
            $s.=$_;
            if(/\)\s*;/o || /\)\s*\{/o){ last;}
         }
      }
      $c=0;
      $s =~ s/,/$c++,","/oge;
      if($s !~ /\(\s*(void)?\s*\)/m){
         $c++;
      }
      if($md{$.}[2] || $md{$.}[0] =~ /Const/o){
         push @{$redef{$class}{$md{$.}[1]}},[$.,$c];
      }else{
         push @{$redef{""}{$md{$.}[1]}},[$.,$c];
      }
      $md{$.}[1] =~ s/^new_//o;
      print "%name($md{$.}[1]__L$.) $s";
      
      next;
   }
   print;
}
close(IFILE);

print "%pragma(python) include=\"$mod\_overloaded.py\"\n";

open(F,">${mod}_overloaded.py");
for $cl(keys %redef){
 if($cl ne ""){
   print F "
class $cl\($cl):\n";
   for $f(keys %{$redef{$cl}}){
      $el=""; 
      if($f =~ /^new_/o){
         $clname="";
         print F "    def __init__\(self,*args):\n";
      }else{
         $clname="${cl}_";
         print F "    def $f\(*args):\n";
      }
      for $i(@{$redef{$cl}{$f}}){
         print F "        ${el}if len(args)==$i->[1]:\n";
         print F "            val = apply(${mod}c.${clname}${f}__L$i->[0],args)\n";
         $el="el";
      }
      print F "        else:  val = apply(${mod}c.${clname}${f},args)\n";
      if($f !~ /^new_/o){ print F "        return val\n";}
   }
 }else{
   for $f(keys %{$redef{$cl}}){
      $el=""; 
      print F "def $f\(*args):\n";
      for $i(@{$redef{$cl}{$f}}){
         print F "    ${el}if len(args)==$i->[1]:\n";
         print F "        val = apply(${mod}c.${clname}${f}__L$i->[0],args)\n";
         $el="el";
      }
      print F "    else:  val = apply(${mod}c.${clname}${f},args)\n";
      print F "    return val\n";
   }
 }
}
close(F);


16. Wrapping a C++ class with an overloaded constructor.
[Detail] I got a class with a constructor/method accepting different setting of arguments.
class Foo {
public:
  %name (Foo_A) Foo();
  %name (Foo_B) Foo(int i);
  %name (Foo_C) Foo(float f);
...};
In Python, it should be able to identify the arugments and make a corresponding constructor.

[Answer] I got a tricky method. Put the following line in your interface file:

%pragma(python) include="override_Foo_init.py"
In override_Foo_init.py:
class Foo(Foo):   # <=== Tricky here!
   def __init__(self,*_args,**_kwargs):
      if len(_args)==0:
         self.this = apply(Fooc.new_Foo_A,_args,_kwargs)
      elif type(_args[0])==type(1):
         self.this = apply(Fooc.new_Foo_B,_args,_kwargs)
      elif type(_args[0])==type(0.1):
         self.this = apply(Fooc.new_Foo_C,_args,_kwargs)
      self.thisown = 1


17. Enforcing the order in which variables are converted from scripting types to C types.
[Detail] Suppose you have the following function:
    void foo(int *argX, int *argY);
A %typemap(python, in) exists for both the variables. Is there any way to force the %typemap(in) for argX to be executed before the %typemap(in) for argY? This would be useful, for example, in cases where argY in a 3 element array holding the dimensions of the 3D array pointed to by argX.

[Answer] Although the method below is tricky, you can do it by swapping function definitions in SWIG and C twice, for example,

%{
#define fake_foo(arg1,arg2,arg3) foo(arg3,arg1,arg2)
%}
int fake_foo(char *arg1,char *arg2,char *arg3);
%pragma(python) code="def foo(arg3,arg1,arg2):
    return fake_foo(arg1,arg2,arg3)";
fake_foo() is the function prototype seen by SWIG, and therefore it is converted as expected. However, we call it by the way it is originally defined i.e. foo().


18. Typemaps for fixed length buffer.
[Detail] I am trying to wrap a 'C' function for Python. I have the following line in my '.i' file:
     MsOle * msOleString(char *str, int length);
It generates the following wrapper 'C' code:
     if(!PyArg_ParseTuple(args,"si:msOleString",&_arg0,&_arg1))
What I NEED is:
     if(!PyArg_ParseTuple(args,"s#:msOleString",&_arg0,&_arg1))
If I hand edit the wrapper 'C' code than all is well. When I do not, then an exception is generated because my _arg0 contains '\0' in the middle of the buffer.

[Answer] Try this:

%typemap(python,in) char *str{
   if (PyString_Check($source)) {
      $source=Py_BuildValue("(O)",$source);
      if(!PyArg_ParseTuple($source,"s#:msOleString",&$target,&arg1)) 
         return NULL;
   }else{
      PyErr_SetString(PyExc_TypeError,"not a string type");
      return NULL; 
   }
}
%typemap(python,ignore) int length{
}


19. Implicit size typemap of an input array.
[Detail] I'm trying to make a wrapper using the Numeric package in python. Say, I want to wrap the function defined by
 void f(double* a, int n)
 {
   int i;
   for(i=0;i<n;i++)
     a[i] = double(i)/double(n);
 }
with some help from the Numpy list I managed to get a working interface such as:
 >>> import Numeric
 >>> import NumExt
 >>> a = Numeric.arange(0.0,10.0)
 >>> NumExt.f(a,len(a))
I would like a more elegant interface, not having to submit the length of the array a:
    
 >>> NumExt.f(a)

[Answer] The trick is to set up a pointer to the input $target.

%module pass_info
%typemap(python,ignore) int n(int *ptr_n){
   ptr_n=&$target;
}

%typemap(python,in) double *a{
   int i,size;
   *ptr_n=size=PyList_Size($source);
   $target=(double *)malloc(sizeof(double)*size);
   for(i=0;i<size;i++){
      $target[i]=PyFloat_AsDouble(PyList_GetItem($source,i));
   }
}

%typemap(python,freearg) double *a{
   free($source);
}

%inline %{
#include <stdio.h>
void f(double* a, int n)
{
  int i;
  for(i=0;i<n;i++)
    a[i] = (double)i/(double)n;
}
%}


20. Input typemap for array(or STL vector) of pointers.
[Detail] There is a function in the SDK -
extern int SmDefineVocab(char *,short ,*SM_VOCWORD[] ,SM_MSG *);
SM_VOCWORD expects an array of pointers. What is the typemap for SM_VOCWORD ** ?
[Answer] The key point is to wrap the object extracted from a Python list by SWIG_ConvertPtr. Also, remember to release the extra memory by using freearg typemap.
%define array_in(T)
%typemap(python,in) T **{
    if(PyList_Check($source)) {
        int size = PyList_Size($source);
        int i = 0;
        $target = (T **) malloc(size*sizeof(T*));
        for(i = 0; i < size; i++) {
            PyObject *o = PyList_GetItem($source,i);
            T *ptr;
            if ((SWIG_ConvertPtr(o,(void **) &ptr,
               SWIGTYPE_p_##T,1)) == -1) return NULL;
            $target[i] = ptr;
        }
    } else {
      PyErr_SetString(PyExc_TypeError,"not a list type");
      return NULL; 
    }
}
%typemap(python,freearg) T **{
    free($source);
}
%typemap(perl5,in) T **{
   if (!SvROK($source))
      croak("$source is not an array.");
   if (SvTYPE(SvRV($source)) != SVt_PVAV)
      croak("$source is not an array.");
   tempav = (AV*)SvRV($source);
   len = av_len(tempav);
   $target = (T **) malloc(len*sizeof(char *));
   for (i = 0; i <= len; i++) {
      tv = av_fetch(tempav, i, 0);	
      T *ptr;
      if ((SWIG_ConvertPtr(av,(void **) &ptr,
           SWIGTYPE_p_##T,1)) == -1) return NULL;
      $target[i] = ptr;
   }
}
%typemap(perl5,freearg) T **{
    free($source);
}
%enddef 
You can use this array_in macro in the interface file to create typemap for SM_VOCWORD:
array_in(SM_VOCWORD);


21. Pointer typecasting in an output list or STL vector.
[Detail] I need to cast a C/C++ pointer to a SWIGified pointer in a STL vector.

[Answer] Using the following multi-line macro definition in SWIG, you can make it very generic:

%define vector_typemap(T)
%typemap(python,out) vector<T *> *, vector<T *> &{ 
 $target = PyList_New(0);
 if($source){
    for(vector<T *>::iterator i=$source->begin();
              i!=$source->end();i++){
       PyObject *o=SWIG_NewPointerObj((void *)(*i), SWIGTYPE_p_##T);
       PyList_Append($target,o);
       Py_XDECREF(o);
    }                       
    //delete $source; //depends on your code
 }
}
%typemap(perl5,out) vector<T *> *, vector<T *> &{
 if($source){
    if($source->size()>items){
       EXTEND(sp,$source->size()-items);
    }
    for(vector<T *>::iterator i=$source->begin();
               i!=$source->end();i++){
       ST(argvi) = sv_newmortal();
       SWIG_MakePtr(ST(argvi++), (void *)(*i), SWIGTYPE_p_##T);
    }
    //delete $source; //depends on your code
 }
}
%enddef
For example, you have a "Cell" vector to be SWIGified. Use the following code in your interface file:
vector_typemap(Cell);
You can check this by
swig -E your_interface_file.i


22. Generic pointer argout typemap.
[Detail] How can I handle argout for a structure? For example,
struct rtype { };
int foo(rtype *OUTPUT);
foo will fill the contents of the structure pointed by OUTPUT.

[Answer]

%include typemaps.i
%define ptr_argout(T)
%typemap(python,argout) T* OUTPUT{
    PyObject *o=SWIG_NewPointerObj((void *)$source, SWIGTYPE_p_##T);
    $target = l_output_helper($target,o);
}
%typemap(python,ignore) T* OUTPUT{
    static T temp;
    $target=&temp;
}
%typemap(perl5,argout) T* OUTPUT{
    PyObject *o=SWIG_NewPointerObj((void *)$source, SWIGTYPE_p_##T);
    $target = l_output_helper($target,o);
}
%typemap(perl5,ignore) T* OUTPUT{
    static T temp;
    $target=&temp;
}
%enddef
Now, you can use:
ptr_argout(rtype,OUTPUT);
int foo(rtype *OUTPUT);
Remember the return structure is a static type variable. You can not keep the value in the previous call.

It is also possible to allocate memory for it, for example:

%include typemaps.i
%define ptr_argout(T)
%typemap(python,argout) T* OUTPUT{
    PyObject *o=SWIG_NewPointerObj((void *)$source, SWIGTYPE_p_##T);
    $target = l_output_helper($target,o);
}
%typemap(python,ignore) T* OUTPUT{
    $target=(T*)malloc(sizeof(T));
}
%addmethods T{
    ~T(){
        free(self);
    }
}
%enddef


23. Argument out typemaps for pre-allocated buffer.
[Detail] I have a function:
     int khepera_receive_serial(int max_length, char *buffer);
The caller is responsible to allocate a buffer with max_length bytes, and the function return the actual length used. In Python, it should end up looking like:
      >>> (length, buffer) = khepera_receive_serial( max_length )

[Answer] Try this,

%typemap(python,ignore) char *buffer(char **temp){
   temp=&$target;
}
%typemap(python,in) int max_length{
   $target=PyInt_AsLong($source);
   *temp=(char*)malloc($target);
}
%typemap(python,argout) char *buffer{
   PyObject *o; 
   o = Py_BuildValue("s#",$source,result);
   $target = t_output_helper($target, o); 
   free(*temp); 
}
Basically, we create a char **temp to point back to the real argument and allocate memory. When we know the max_length, we do the allocation. *temp guarantees the argument pointer is correctly pointed to. For the output buffer, we create a Python representation of a string with known length(i.e. result).


24. Argument out typemaps for a C++ reference to a pointer.
[Detail] We have several objects with methods of the following form:
 Status GetItemAtIndex(int theIndex, Object* &item);
which return a particular item from a list. Swig throws an error on this construction in an interface file. While removing the & allows the compilation of the interface, when I try to access 'item' in this manner, the value of 'item' is not that of the one in the list.

[Answer] You need to

  1. Write the typemap to handle argument out.
  2. Wrap the output with Python class pointer. This can be done either in C++ or Python.
Check "Generic argout typemaps for objects" for details. The following code is an example:
shadowClassPtr(Object); // Make a C function ObjectPtr() 
obj_argout(Object);     // Make %typemap(python,argout) Object *REF_PTR{...}
typedef int Status;
// Notice that you should use Object *REF_PTR, instead of Object* &item!
Status GetItemAtIndex(int theIndex,Object* REF_PTR);


25. Argument out typemaps for C++ reference.
[Detail] In my C++ class, I have the following method:
   int GetGroupPriority(int32 groupID, uint8& priority);
priority is an output argument, which is type defined as unsigned char. From Python, I'd like to call it as such:
 error, priority = classInst.GetGroupPriority(32)

[Answer] Using typemaps.i, you can do it as follows

%include typemaps.i
%apply unsigned char* T_OUTPUT{ unit8& OUTPUT};
int GetGroupPriority(int groupID, unit8& OUTPUT);


26. Generic argout typemaps for objects/Difference in argout typemaps.
[Detail]What is the difference in the argout typemap for C++ reference, single pointer and double pointer to an "argout" object?

[Answer] See the following code:

%{
#define SWIG_module_name "Put_MyModuleName_here" 
static PyObject *MyModuleName; 
%}
%init %{
    MyModuleName=PyImport_ImportModule(SWIG_module_name);
%}

%define shadowClassPtr(T) 
%{ 
static PyObject *T##Ptr_o=NULL; 
PyObject *T##Ptr(void *source,int own) {
    char cbuf[512];
    PyObject *o;
    if(T##Ptr_o==NULL)T##Ptr_o=PyObject_GetAttrString(MyModuleName,"T""Ptr");
    SWIG_MakePtr(cbuf,(void*)(source),SWIGTYPE_p_##T);
    o=PyObject_CallFunction(T##Ptr_o, "(s)",cbuf);
    if(own){
       PyObject *val = PyInt_FromLong(1L);
       PyObject_SetAttrString(o, "thisown", val); 
    }
    return o;
}
%} 
%enddef
// Declare a C function FooPtr() here
shadowClassPtr(Foo);

%include typemaps.i

%define obj_argout(T)
%inline %{
typedef T* T##ptr;
%}

%typemap(python,argout) T **, T##ptr &, T* REF_PTR{
   PyObject *o=T##Ptr((void*) *$source,1);
   $target = t_output_helper($target, o);
}
%typemap(python,ignore) T **,T##ptr &(T *temp){
   $target=&temp;
}
%typemap(python,ignore) T* REF_PTR{
}
%typemap(python,argout) T *OUTPUT,T &{
   PyObject *o=T##Ptr((void*) $source,1);
   $target = t_output_helper($target, o);
}
%typemap(python,ignore) T *OUTPUT, T &{
   $target=new T();
}
%enddef
// Define each type of argout typemaps
obj_argout(Foo);

// SWIG does not parse Foo* &p. Workaround is as follows:
void ret_Foo_refptr(Foo *REF_PTR);
%{
void ret_Foo_refptr(Foo *&p){
   p=new Foo("Foo returns by ref ptr!");
}
%}
Single pointer and reference are almost the same in terms of typemap code; However, the double pointer approach imposes the memory allocation responsibility on the C/C++ routine itself.

[Perl] For Perl, you need to have a helper function(e.g. FooPtr2Obj) to achieve object shadowinig. SWIG usually gives a blessed scalar instead of a blessed tied hash. We need to do it in a Perl helper function like this:

// Assume using swig -perl5 -shadow -compat
%define shadowClassPtr(T)
%{
SV* T##Ptr2Obj(void *src){
   HV *hv=newHV();
   SV *rv;
   SV *sv = sv_newmortal();
   SWIG_MakePtr(sv, (void *)src, SWIGTYPE_p_##T);
   sv_magic((SV*)hv,sv,(int)'P',Nullch,0);
   rv=newRV_noinc((SV*)hv);
   sv_2mortal(rv);
   return sv_bless(rv, SvSTASH(SvRV(sv)));
}
%}
%enddef
// Declare a C function FooPtr2Obj() here
shadowClassPtr(Foo);

%define obj_argout(T)
%inline %{
typedef T* T##ptr;
%}
%typemap(perl5,argout) T**, T##ptr &, T* REF_PTR{
   if (argvi >= items) EXTEND(sp,1);
   ST(argvi++)=T##Ptr2Obj((void *)*$source); // shadowing
   //Uncomment the following two lines if no object shadowing
   //ST(argvi) = sv_newmortal();
   //SWIG_MakePtr(ST(argvi++), (void *)*$source, SWIGTYPE_p_##T);
}
%typemap(perl5,ignore) T **,T##ptr &(T *temp){
   $target=&temp;
}
%typemap(perl5,ignore) T* REF_PTR{
}
%typemap(perl5,argout) T* OUTPUT,T &{
   if (argvi >= items) EXTEND(sp,1);
   ST(argvi++)=T##Ptr2Obj((void *)$source);
   //Uncomment the following two lines if no object shadowing
   //ST(argvi) = sv_newmortal();
   //SWIG_MakePtr(ST(argvi++), (void *)$source, SWIGTYPE_p_##T);
}
%typemap(perl5,ignore) T *OUTPUT,T &{
   $target=new T();
}
%enddef


27. Object pointer does not get shadowed.
[Detail] Some of C++ objects created by Python can not be deleted. See:
 >>> s = ipol2.Evaluate(3)
 >>> s
 '_41071eb8_p_pfQuat'
 >>> t = pfQuat()
 >>> t
 <C pfQuat instance at _41071ee8_p_pfQuat>
So t is regarded as a true instance; s is regarded as a mere pointer. Now, if I call 'del t', the SWIG generated
 static PyObject *_wrap_delete_pfQuat(PyObject *self, PyObject *args)
is called. If I call 'del s', this SWIG func is not called. And with UNIX top, I can see that there is a mem leak: The python ptr object is probably deleted, but the underlying C++ object is not. How can I fix this?

[Answer] Remember to write your function prototype after class definition in your interface file. I tried an interface file like this:

%module delobj

pfQuat Evaluate();
%inline %{
class pfQuat{
public:
   pfQuat(){ }
   ~pfQuat(){ printf("object deleted in C++(%p)\n",this);}
};
%}

pfQuat Evaluate_OK();
%{
pfQuat Evaluate(){
   return *(new pfQuat);
}

pfQuat Evaluate_OK(){
   return *(new pfQuat);
}
%}
You may test it by a script:
from delobj import *

s=Evaluate()
print "s=",s
del s
print "s is not really deleted!"
t=Evaluate_OK()
print "t=",t
del t
print "t should be deleted"
print "End of test_delobj"
Note that '_41071eb8_p_pfQuat' is not an object pointer for SWIG, but it is a struct pointer, which does not imply any delete C++ object operation; instead, <C pfQuat instance at _41071ee8_p_pfQuat> is actually printed out by
pfQuat.__repr__
and this is a clue that this Python variable has been attached to a Python object. Check the difference in *.py file SWIG generated:
Evaluate = delobjc.Evaluate

def Evaluate_OK(*args, **kwargs):
    val = apply(delobjc.Evaluate_OK,args,kwargs)
    if val: val = pfQuatPtr(val); val.thisown = 1
    return val


28. Object typecasting in an output list or STL vector.
[Detail] I am using SWIG to wrap some of the C++ classes used in my MUD(multi-user Dungeon), and I then run the module from inside a Python interpreter which is embedded in my MUD. I am using the -shadow option to generate Python shadow classes for each of the C++ classes. All of this works just great. However I have a situation where I am mapping C++ STL lists into Python lists. I used a %typemap posted by Scott Snyder for doubles and modified it. The objects stored in the Python list are SWIGified C++ custom classes. When I get items out of the list in Python it thinks they are just strings, and so I have to Python "typecast" them with char_classPtr(), which is auto-generated by SWIG.

[Answer] Check this FAQ for how to shadow an object pointer. Here is my sample code:

shadowClassPtr(MyClass);
%define stl_vector_out(MyClass)
%typemap(python,out) vector<MyClass*>*{
    $target = PyList_New(0);
    if($source){
        for(vector<MyClass*>::iterator i=$source->begin();
            i!=$source->end();i++){
            PyObject *optr=MyClass##Ptr((void*)*i,1);
            PyList_Append($target,optr);
            Py_XDECREF(optr);
        }
        // delete $source; // depends on your code
    }
}
%enddef
You can use this macro to call for a Node vector in the module test_obj_cast.
stl_vector_out(test_obj_cast,Node);
More examples for shadowing a pointer are available in this FAQ.

29. Generic shadow object typecasting in C/C++.
[Detail] I got a pointer
'_41071eb8_p_pfQuat'
but what I really want is a shadowed pointer, say, for example,
<C pfQuat instance at _41071ee8_p_pfQuat>.
How can I shadow it in C?

[Answer]

#define new_obj_typecast(MyMod,MyClass,source,target) \
  { \  
    char cbuf[512]; \  
    PyObject *val = PyInt_FromLong(1L);\  
    PyObject *mod=PyImport_ImportModule("MyMod");\  
    PyObject *func=PyObject_GetAttrString(mod,"MyClass""Ptr");\  
    SWIG_MakePtr(cbuf,(void*)source,SWIGTYPE_p_##MyClass);\  
    target=PyObject_CallFunction(func, "(s)",cbuf);\  
    PyObject_SetAttrString(target, "thisown", val);\  
    Py_DECREF(func);\  
    Py_DECREF(mod);\  
  }
If you don't need to own this object, do the following:
#define new_obj_typecast(MyMod,MyClass,source,target) \
  { \  
    char cbuf[512]; \  
    PyObject *mod=PyImport_ImportModule("MyMod");\  
    PyObject *func=PyObject_GetAttrString(mod,"MyClass""Ptr");\  
    SWIG_MakePtr(cbuf,(void*)source,SWIGTYPE_p_##MyClass);\  
    target=PyObject_CallFunction(func, "(s)",cbuf);\  
    Py_DECREF(func);\  
    Py_DECREF(mod);\  
  }
If this shadowing operation happens quite often, you may want to do this:
%{
#define SWIG_module_name "Put_MyModuleName_Here"
static PyObject *MyModuleName;

%}
%init %{
    MyModuleName=PyImport_ImportModule(SWIG_module_name);
%}

%define shadowClassPtr(T)
%{
static PyObject *T##Ptr_o=NULL;
PyObject *T##Ptr(void *source,int own) {
    char cbuf[512];
    PyObject *o;
    if(T##Ptr_o==NULL)T##Ptr_o=PyObject_GetAttrString(MyModuleName,"T""Ptr");
    SWIG_MakePtr(cbuf,(void*)(source),SWIGTYPE_p_##T);
    o=PyObject_CallFunction(T##Ptr_o, "(s)",cbuf);
    if(own){
       PyObject *val = PyInt_FromLong(1L);
       PyObject_SetAttrString(o, "thisown", val);
    }
    return o;
}
%}
%enddef
If you have a class Foo, the following code will create a C function PyObject* FooPtr(void *source,int own) in the interface file:
shadowClassPtr(Foo);
An argout typemap application can be:
shadowClassPtr(Foo);
%typemap(python,argout) Foo **{
   $target=t_output_helper($target,FooPtr((void*)*$source,1));
}
%typemap(python,ignore) Foo **(Foo *temp){
   $target=&temp;
}

[Perl] In general, you don't need this in Perl. The shadowing mechanism in SWIG makes the reference to a shadow object automatically. However, if you need to access the field member, the following code is useful:
// Assume using swig -perl5 -shadow -compat
%define shadowClassPtr(T)
%{
SV* T##Ptr2Obj(void *src){
   HV *hv=newHV();
   SV *rv;
   SV *sv = sv_newmortal();
   SWIG_MakePtr(sv, (void *)src, SWIGTYPE_p_##T);
   sv_magic((SV*)hv,sv,(int)'P',Nullch,0);
   rv=newRV_noinc((SV*)hv);
   sv_2mortal(rv);
   return sv_bless(rv, SvSTASH(SvRV(sv)));
}
%}
%enddef
// Declare a C function FooPtr2Obj() here
shadowClassPtr(Foo);


30. Wrapping a function prototype like foo(int argc, char **argv).
[Detail] I have a function prototype looking like this:
int foo(int argc, char **argv);
How can I wrap it in SWIG and have a variable argument feature in the interface.

[Answer] [Python] You need couple of typemaps:

%typemap(python,ignore) char **argv{
   int i;
   int num_argv=PyTuple_Size(args);
   $target=(char**)malloc(num_argv*sizeof(char *));
   for(i=0;i<num_argv;i++){
      PyObject *o=PyTuple_GetItem(args,i);
      if(PyString_Check(o)){
         $target[i]=PyString_AsString(o);
      /* depending on your need for the following 2 conditions
      }else if(PyInt_Check(o)){
         char tmp[128];
         sprintf(tmp,"%ld",PyInt_AsLong(o));
         $target[i]=strdup(tmp);
      }else if(PyFloat_Check(o)){
         char tmp[128];
         sprintf(tmp,"%g",PyFloat_AsDouble(o));
         $target[i]=strdup(tmp);
         // remember to release memory!
      */
      }else
         $target[i]="(not char *)";
   }
   args=Py_BuildValue("(i)",num_argv);
}

%typemap(python,freearg) char **argv{
   free($source);
   Py_DECREF(args);
}
Now, you can use
foo("No","matter","how","many","arguments","I","got")
foo("it","is","OK")

[Perl5] Use the following code for perl:
%typemap(perl5,in) char **argv {
    $target = (char **)
            malloc(n_arg*sizeof(char *));
    for (; n_arg; --n_arg) {
       $target[n_arg-1]=
            (char *)SvPV(ST(n_arg-1),PL_na);
    }
}
%typemap(perl5,ignore) int argc(int n_arg){
    $target=n_arg=items;
    items=1;
}
%typemap(perl5,freearg) char **argv {
    free($source);
}


31. Operator overloading support.
[Detail] SWIG cannot handle C++ operator overloading. Could I work-around it somehow?

[Answer] Using the following Perl script, you can handle most of the operator overloading code by adding "%addmethods" section.

#!/usr/bin/env perl
if(scalar @ARGV==0 || $ARGV[0] =~ /^-h/oi){
   print STDERR "Usage: perl $0 your_interface_file > new_interface_file\n";
   exit;
}
$refgone="&";
if($ARGV[0] eq "-ref"){
   $refgone="";
   shift @ARGV;
}
%binopmap=(
'<'=>'__lt__', '>'=>'__gt__', '=='=>'__eq__', '!='=>'__ne__',
'<='=>'__le__', '>='=>'__ge__',
'+'=>'__add__', '-'=>'__sub__','*'=>'__mul__', '/'=>'__div__',
'&'=>'__and__', '^'=>'__xor__','|'=>'__or__', '%'=>'__mod__',
'+='=>'__iadd__','-='=>'__isub__','*='=>'__imul__','/='=>'__idiv__',
'&='=>'__iand__','^='=>'__ixor__','|='=>'__ior__','%='=>'__imod__',
'<<'=>'__lshift__','>>'=>'__rshift__',
'[]'=>'__getitem__'
);
%unopmap={ '-' =>'__neg__','+' =>'__pos__'};

$ifile=shift @ARGV;
open(IFILE,$ifile);
$cmtout="//";
while(<IFILE>){
   if(m|^\s*//|o){ print; next;} 
   elsif(/\%inline/o){ $cmtout="";}
   elsif(/\%\}/o){ $cmtout="//";}
   elsif(/class\s+(\w+)/o){ $class=$1;}
   elsif(/\boperator\b\s*[^\w\s]+\s*\(/o){
      $s=$_; $h=$_;
      if($_ !~ /^(.+?)operator\s*(\W+?)\s*\(/o || !exists $binopmap{$2}){
         print STDERR "Operator overloading at Line $. cannot be translated!\n   =>$_";
         print $_; next;
      }
      $rettype=$1; $op=$2;
      print "$cmtout$_";
      if($_ !~ /;/o && $_ !~ /\{/o){
         while(<IFILE>){
            print "$cmtout$_";
            $s.=$_; 
            if(/;/o){ last;}
         }
      }elsif($_ =~ /\{/o){
         $p=1;
         while(<IFILE>){
            print "$cmtout$_";
            $s.=$_;
            s/([\{\}])/if($1 eq "{"){$p++}else{$p--} $1/goe;
            if($p==0 && /\}/o){ last;}
         }
      }
      $s=~ /\(\s*(.*)\s*\)/mo;
      $param=$1;
      if($param =~ s/((const\s+)?\w+\s*[^\w\s]*)\s*\w+$/$1 oprnd2/o){
      }elsif($param =~ s/((const\s+)?\w+\s*[^\w\s]*)$/$1 oprnd2/o){ }
      if(!exists $addmethods{$class}){
         $addmethods{$class}="%addmethods $class\{\n";
      }
      if($op eq "[]"){
         $h =~ s/^(.+?)\s*$refgone\s*operator\s*(\W+?)\s*\((.*)\).*$/$1 $binopmap{$op}\($param){/o; 
         $addmethods{$class}.=$h."     return (*self)[oprnd2];\n   }\n";
         $rettype =~ s/$refgone//o;
         $h =~ s/^.*?__getitem__\s*\(.*?\)/   void __setitem__($param,$rettype _value)/o;
         $h .= "     (*self)[oprnd2]=_value;\n   }\n";
      }else{
         $h =~ s/^(.+?)operator\s*(\W+?)\s*\((.*)\).*$/$1 $binopmap{$op}\($param){/o;
         $h .= "     return *self $op oprnd2;\n   }\n";
      }
      $addmethods{$class}.=$h;
      next;
   }
   print;
}
close(IFILE);
print "\n// ----------- Operator overloading code ----------\n";
for $c(keys %addmethods){
   print "$addmethods{$c}\n};\n";
}
Suppose you have a class declaration:
class Foo {
public:
   Foo(int _i);
   bool operator ==(Foo &y);
   Foo& operator +=(Foo &y);
   int& operator [](int i);
}
Running the script, you will get:
class Foo {
public:
   Foo(int _i);
//   bool operator ==(Foo &y);
//   Foo& operator +=(Foo &y);
//   int& operator [](int i);
   }
};
// ----------- Operator overloading code ----------
%addmethods Foo{
   bool  __eq__(Foo & oprnd2){
     return *self == oprnd2;
   }
   Foo&  __iadd__(Foo & oprnd2){
     return *self += oprnd2;
   }
   int __getitem__(int  oprnd2){
     return (*self)[oprnd2];
   }
   void __setitem__(int  oprnd2,   int  _value){
     (*self)[oprnd2]=_value;
   }
};


32. Wrapping "friend ostream& operator<<" in Python
[Detail] How can I wrap
friend ostream& operator<<(ostream& os, const Foo& foo);
this kind of stream-out operator?

[Answer] Use the following code:

%{
#include <iostream.h>
#define op_lshift(T) \
else if((SWIG_ConvertPtr(din,(void **)&arg,SWIGTYPE_p_##T,1)) != -1)\
     return (*self << *(T*)arg)
%}
%typemap(python,in) PyObject*{
   $target=$source;
}
class ostream{ };
%addmethods ostream{
   ostream& __lshift__(PyObject *din){
      void *arg;
      if(PyString_Check(din)){
         *self << (char*)PyString_AsString(din);
         return *self;
      }else if(PyInt_Check(din)){
         *self << (long)PyInt_AsLong(din);
         return *self;
      }else if(PyFloat_Check(din)){
         *self << (double)PyFloat_AsDouble(din);
         return *self;     }
      op_lshift(MyClass);
      op_lshift(MyClass2);
      op_lshift(MyClass3);
      //...
   }
}
%inline %{
ostream* cout_get(){
   return &cout;
}
%}
op_lshift() macro can be used to create more operator loading. cout_get() is used to get a "cout" in Python.

33. Reducing Perl shadowing scheme overhead.
[Detail] Perl shadowing object seems using a huge structure to wrap it up such as a tied reference. If I don't use any public data member, can I reduce it?

[Answer] If you don't expose any data field into public, you may use the following Perl script(reduceSWIGpm.pl) to simplify the shadowing scheme:

#!/usr/bin/env perl -i.bak
while(<>){
   if(/^\s*sub\s+new\s*\{/o){
      print;
      while(<>){
         if(/^\s*bless\s+\$self,/){
            next;
         }elsif(s/\$OWNER\{\$s/\$OWNER\{\$\$s/o){ last;}
         print;
      }
      print;
      while(<>){
         if(/return/o){ last;}
      }
      $_="    return \$self;\n";
   }elsif(/^\s*my\s+%resulthash;/o){
      $_=<>; $_=<>;
      $_="    return \$result;\n";
   }elsif(/^\s*sub\s+this\s*\{/o){
      print;
      $_=<>; $_=<>;
      $_="\n    return \${\$_[0]};\n";
   }
   if(/^\s*return unless/o && /'HASH'/o){ $_ ="#$_";}
   s/(::delete_\w+)\((\S+?)\)/$1\(\$_[0])/o;
   s/tied\(%(\S+?)\)/\$$1/og;
   print;
}
Under unix, run this
unix< perl reduceSWIGpm.pl MyModule.pm
It will copy your original '*.pm' to '*.pm.bak' and give you something like this:
package MyClass;
@ISA = qw( t Sclass );
%OWNER = ();
%ITERATORS = ();
sub new {
    my $self = shift;
    my @args = @_;
    $self = tc::new_MyClass(@args);
    return undef if (!defined($self));
    $OWNER{$$self} = 1;
    return $self;
}

sub DESTROY {
#    return unless $_[0]-<isa('HASH');
    my $self = ${$_[0]};
    delete $ITERATORS{$self};
    if (exists $OWNER{$self}) {
        tc::delete_MyClass($_[0]);
        delete $OWNER{$self};
    }
}
sub foo {
    my @args = @_;
    my $result = tc::MyClass_foo(@args);
    return undef if (!defined($result));
    return $result;
}

sub DISOWN {
    my $self = shift;
    my $ptr = $$self;
    delete $OWNER{$ptr};
    };
...
I test it on a simple script and it works fine with SWIG1.3a5. It may not apply to all the cases. Use it with care!

34. Detecting dependency between header files
[Detail] I got several headers but have no idea which one should be included first in my interface file.

[Answer] Try the following Perl script(detectDep.pl) to detect this dependency:

#!/usr/bin/env perl

$inc_sys=0;
if($ARGV[0] eq "-s"){
   print STDERR "Include system header files...\n";
   $inc_sys=1;
}
$args=join(" ",@ARGV);
open(F,"grep '#include' $args|");
while(<F>){
   if(/(\S+?):\s*#include\s+"(\S+?)"/o){
      $depend{$1}{$2}=1;
   }elsif($inc_sys && /(\S+?):\s*#include\s+\<(\S+?)\>/o){
      $h=$1; $dep=$2;
      $depend{$h}{$dep}=1
   }   
}
close(F);

for $f(keys %depend){
   print_h($f);
}
sub print_h{
   my ($h)=@_;
   my $d;
   if(exists $visited{$h}){
      return;
   }
   $visited{$h}=1;
   for $d(keys %{$depend{$h}}){
      print_h($d);
   }
   print "$h\n";
   return;
}
Run it with
find . -name \*.h -print|perl detectDep.pl 


35. C++ complains about incompatible types in assignment of char[] for a struct field set function.
[Detail] g++ complains that '_wrap.c' has a problem:
./foo_wrap.c:1415:incompatible types in assignment of 'char *' to 'char[128]'
where I have a struct declaration in '*.i':
#define FSTRING_LEN 128
typedef char fstring[FSTRING_LEN];
struct cli_state
{ ...
  fstring server_type;
  ..
};

[Answer] You need to insert two typemaps:

%typemap(python,memberin) fstring {
   strncpy($target,$source,sizeof(fstring));
}
%typemap(python,memberout) fstring {
   $target=Py_BuildValue("s#",$source,sizeof(fstring));
}


36. Structure marshaling code/typemap.
[Detail] Now I'm trying to do something more complicated: generate structure marshaling code. There is a brief example that talks about doing this using a typemap. This is pretty different from how SWIG is used today, but fits the general directions discribed in the whitepaper.

[Answer] I got a tool that generate the marshaling code automatically. Say, for example, you got a vector structure to wrap:

struct vector{
   float x,y;
   struct Ptr *ptr;
};
My script will generate a pair of typemaps for you:
%typemap(python,out) struct vector {
        struct vector *arg0 =$source;
    PyObject *obj_x,*obj_y,*obj_ptr;
   {
     float result ;
     result = (float ) (arg0->x);
     obj_x = PyFloat_FromDouble(result);
   }
    {
     float result ;
     result = (float ) (arg0->y);
     obj_y = PyFloat_FromDouble(result);
   }
    {
     struct Ptr *result ;
     result = (struct Ptr *) (arg0->ptr);
     obj_ptr = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_Ptr);
   }

    resultobj = Py_BuildValue("[OOO]",obj_x,obj_y,obj_ptr);
    Py_DECREF(obj_x);
    Py_DECREF(obj_y);
    Py_DECREF(obj_ptr);
    free($source);
}
%typemap(python,in) struct vector {
        float arg_x ;
    float arg_y ;
    struct Ptr *arg_ptr ;
    PyObject *obj_ptr;

    static struct vector temp;

    $target=&temp;
    $source=PyList_AsTuple($source);
    if(!PyArg_ParseTuple($source,"ffO",&arg_x,&arg_y,&obj_ptr))return NULL;
    $target->x = arg_x;
    $target->y = arg_y;
    if ((SWIG_ConvertPtr(obj_ptr,(void **) &arg_ptr,SWIGTYPE_p_Ptr,1))== -1) return NULL;
    $target->ptr = arg_ptr;
}
Currently, Perl5, Tcl8 and Python are supported, and working with SWIG1.3a5. The script will try to hack the code generated by SWIG and rearrage them into "out" and "in" typemaps. I will put the script in http://www-cad.eecs.berkeley.edu/~pinhong/scriptEDA


37. Automatic callback generation.
[Detail] I got a function pointer variable. How can I make a Python callback function?

[Answer] I just implemented Perl5, Tcl8, and Python callback support in SWIG1.3a5. (http://www-cad.eecs.berkeley.edu/~pinhong/scriptEDA) For example, if you got a interface file like this:

%module testcb
%inline %{
int  (*C_func)(double a, char *msg);
void exec_callback(){
   int ret;
   ret=(*C_func)(1.0,"test CB_FUNC OK!");
   printf("*C_func return=%d\n",ret);
}
%}
Using the tool, you can get a new interface file:
%module testcb
%{
static PyObject* PyCallBack_C_func=0;
 int _cbwrap_C_func(double a,char *msg){
    PyObject *arglist,*result;
    int ret ;

    PyObject *arg0, *arg1;
    if(!PyCallBack_C_func)return ret;
    arg0 = PyFloat_FromDouble(a);
    {
        arg1=Py_BuildValue("s",msg);
    }

    result=PyObject_CallFunction(PyCallBack_C_func,"(OO)",arg0,arg1);
    { PyObject *args=Py_BuildValue("(O)",result);
      Py_XDECREF(result);
          if(!PyArg_ParseTuple(args,"i:CALLBACK",&ret)) return (int) NULL;

      Py_XDECREF(args);
    }
    return ret;
}
%}
%typemap(python,in) PyObject *{ $target=$source;}
%inline %{
void register_C_func(PyObject *pyfunc){
    if (!PyCallable_Check(pyfunc)) {
      PyErr_SetString(PyExc_TypeError, "Need a callable object!");
      return;
    }
    if(PyCallBack_C_func)Py_DECREF(PyCallBack_C_func);
    PyCallBack_C_func=pyfunc;
    Py_INCREF(pyfunc);
}
/* For SWIG Type Conversion */
void __null__C_func(int ret, double a,char *msg){}
%}
%{
 int  (*C_func)(double a, char *msg);
%}

%init %{
    C_func=_cbwrap_C_func;
%}
%inline %{
void exec_callback(){
   int ret;
   ret=(*C_func)(1.0,"test string here");
   printf("*C_func return=%d\n",ret);
}
%}
We could test it in Python by
from testcb import *
def plcb(a,b):
   print "A=",a,"B=",b
   return 133

register_C_func(plcb)
exec_callback()
The output would be
*C_func return=133
A=1, B=test string here


38. Case study for Perl5, Tcl8 and Python comparison.
[Detail] I did some experiment on a non-trival case using SWIG to wrap a C++ library(which uses object and STL extensively), and got some performance figures.

[Answer] I use: SWIG1.3a5 gcc 2.95.2 with -O3 for all the compilation and strip dynamic object code Here is the result:

                  RunTime      Memory Usage
Pure C++           3.69s        6.7M
Perl5.00503       16.74s       ~7M
Tcl8.3.2          18.75s      ~11M
Python2.0         30.84s      ~10M
The library is a parser used to read in a data file, and dump out by scripting language APIs. The runtime is measured by "time" command on UNIX, and memory usage is roughly measured from "ps" command. Note that this method includes all the overheads. The code looks like this in Python:
#!/usr/bin/env python
from pythongnd import *
import sys
sdf=read_sdf(sys.argv[1])

for i in sdf.all_cells():
   for j in i.all_iopaths():
       print  "    (IOPATH",
       if j.cond(): print "(COND",j.cond(),
       print dump_edge(j.begin()),dump_edge(j.end()),
       for t in j.all_triples():
           if not t: print "()",
           else: print "(%.3f:%.3f:%.3f)" % (t.min(),t.typ(),t.max()),
       if j.cond(): sys.stdout.write(")")
       sys.stdout.write(")\n")
   print "    )"
   print "  )"
I did make sure there is no memory leak during this dumping in scripting languages. Actually, Tcl code is annoying because I have to explicitly release memory by rename $var {}. Except that, Tcl, Perl, and Python are very similar. C++ code is quite different since it is hard coded in object methods.

I should clarify that the parser is by Yacc(using bison) and Lex(using flex), and all the three packages use the same C parser. The data format is quite complicated which may not be suitable for coding in just regex in Perl. I did try to use byacc for generating Perl parser code and hand coded regular statement for lexical analyzer, which turns out to be quite slow compared with C version.

One important issue is how you build the internal database. When parsing, C code parser is building its internal database at the same time. If native Perl code is used, it can use lots of space just to store that database, which in turn consumes a lot of runtime.


39. 2-D argout typemaps.
[Detail] SWIG does not wrap
int directory_list(char *url, char dirs[512][255]);
properly? It does not give me a "dirs" list!

[Answer] Check the following "working" example. You need to figure out if your C routine allocates char buffer or not, how to determinate the last string, and if you need to copy 255 chars to Python or not.

%include typemaps.i 
%typemap(python,ignore) char *dir[512]{ 
  static int initialized=0; 
  static char *tmp[512]; 
  if(!initialized){ 
     int i; 
     for(i=0;i<512;i++) 
        tmp[i]=(char*)malloc(255); 
     initialized=1; 
  } 
  $target=tmp; 
} 
%typemap(python,argout) char *dir[512] { 
  int len,i; 
  PyObject *o; 
  len = 0; 
  while(len<512 && *($source[len])!='\0')len++; 
  o = PyList_New(len); 
  for (i = 0; i < len; i++) { 
     // Uncomment the following line if
     // output a fixed length (255 chars) string
     // PyList_SetItem(o,i,Py_BuildValue("s#",$source[i],255)); 
     
     PyList_SetItem(o,i,Py_BuildValue("s",$source[i])); 
  } 
  $target = l_output_helper($target,o); 
} 
%} 


40. C preprocessor directive pass-through.
[Detail] I have to use another class function to wrap a class function conditionally. Is that possible that SWIG by-passes the C preprocessor directives?

[Answer] Try to precede # with %:

void SomeClassF() {
        %#if SOME_FLAG
        // some code
        %#else
        ///
        %#endif
   }


41. Makefile generation for SWIG compilation.
[Detail] Is there any Makefile generation script I can use to speed up putting a Makefile together?

[Answer] Here is an example, which uses Perl's Makefile.PL to create Perl, Python or Tcl modules given a module name.


999. FAQ Template.
[Detail] Here goes the question detail description.

[Answer] Answer here.