July 2001 (using SWIG1.1p5)
Updated December 2001 (using SWIG-1.3.9)
Updated again December 2005
This is a selective and subjective account which it is hoped will show the reader how to use SWIG in a real-life situation. It is no substitute for the SWIG User Guide. And it may well change as I discover my mistakes.
SWIG can be found at http://www.swig.org/. One should also look at the Boost Python Library but I haven't. See this comparison.
/* File: cmtzlib.i */ %module cmtz %{ #include "mtzdata.h" %} %include "cmtzlib.h"%module specifies the name of the Python module to be created. %{ and %} bracket code that is to be included as is, in this case an include preprocessor directive that is necessary for the wrapper functions. %include includes a header file which lists the functions for which we want wrappers.
%inline can be used to define additional functions for the Python API which don't exist in cmtzlib.h, for example:
%inline %{ float refdata_get(MTZCOL *col, int i) { return col->ref[i]; } void refdata_set(MTZCOL *col, int i, float f) { col->ref[i] = f; } %}
swig -python cmtzlib.iThis generates a file cmtzlib_wrap.c which contains python-callable wrapper functions, based on the ones declared in cmtzlib.h If you have a non-standard installation, you may need to set the SWIG_LIB environment variable.
gcc -c -I/usr/include/python2.4 -o cmtzlib_wrap.o cmtzlib_wrap.c ld -shared --whole-archive libccp4c.a cmtzlib_wrap.o -o cmtzmodule.soOn SGI:
cc -n32 -c -I/usr/local/include/python1.5 -o cmtzlib_wrap.o cmtzlib_wrap.c ld -n32 -shared -all libccp4c.a cmtzlib_wrap.o -o cmtzmodule.so
Tell python where to find the shared library: PYTHONPATH=/blah/blah/cmtz
# File: mtzapp.py from cmtz import * mtz = MtzGet('toxd.mtz') ccp4_lhprt(mtz, 1) MtzFree(mtz)
So now I do the same for tcl ....
ld -n32 -shared $(CLIPPYOBJS) -o CLIPPYc.so $(LDFLAGS) /usr/lib32/c++init.o -lm -lC -lCioIf/when I find a neater way, I'll let you know ....
#include"ccp4_lib.h"with no space after the #include confused the SWIG preprocessor. Add a space!
CMMFile *ccp4_cmap_open( const char *, int); void ccp4_cmap_header_print(const CMMFile *);you should be able to call them in python as:
map = ccp4_cmap_open("toxd_aupatt_x.map",0) . . ccp4_cmap_header_print(map)"map" is a pointer to a struct, but python doesn't need to know anything about this struct. EXCEPT: SWIG treats "CMMFile *" and "const CMMFile *" as two different data types, and one gets a TypeError.
My solution is to insert a "#define const " in the .i file, so that "const" is stripped from the wrapper function, although it still exists in the original function.