Friday, April 03, 2009

Notes on using SWIG to import C++ in Python

As a test case using my heasp library which is being converted from C to C++. Created heasp.i file to define interface. Basically a concatenation of the heasp.h, PHA.h and PHAII.h files with the following at the top. Adding additional classes will just require cat'ing their *.h file to the end and adding the appropriate #include at the top. Note the %include of "std_string.i" which is required to make the string arguments work. Similar %include specifications will be required if other STL classes are arguments for methods.

%module heasp

%include "std_string.i"

%{
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

#include "heasp.h"
#include "PHA.h"
#include "PHAII.h"
%}

The interface file is then converted to C++ using

swig -python -c++ -classic heasp.i

which creates heasp_wrap.cxx and heasp.py. These must then be combined with the *.o files to build a shareable library called _heasp.so (note that the _ prefix and .so suffix are required). Compiling heasp_wrap.cxx will require include files from python. On my mac the relevant flag is
-I/Library/Frameworks/Python.framework/Versions/Current/include/python2.5
and on the lab Linux network
-I/usr1/local/include/python2.5

On the mac the command to make the shareable library is
ld -bundle -flat_namespace -undefined suppress -o _heasp.so ${OFILES} heasp_wrap.o -L${HEADAS}/lib -lCCfits_2.1 -lcfitsio_3.12
and on Linux
$(CXX) -shared -o _heasp.so ${OFILES} heasp_wrap.o -L${HEADAS}/lib -lCCfits_2.1 -lcfi
tsio_3.13

The module is loaded into python by
>>> import heasp
On the mac this generates an undefined symbol ___eprintf. This may require an update of Xcode to fix. On linux (running python2.5) there are no problems. Example use is

>>> import heasp
>>> spectrum = heasp.PHA()
>>> spectrum.read('file1.pha',1,1)
>>> spectrum.disp()
>>> spectrum.write('test.pha')

No comments: