Hi Everybody,
since I would like to use Python as a high level control language in a
C++ project, I'm interested in a simple way to wrap C++ objects into
Python objects. However, the existing solutions (like SWIG) seem to be
rather complicated. So I implemented an new tool 'Python<C++>', which is
inlcuded below. Unlike previous approaches, my tool makes use of
templates to automate the generation of wrapper objects. This allows to:
- keep the entire wrapping tool in just 3 header files (no library
or code generator required)
- keep the C++ code essentially independent of Python (no inheritance
from PyObject or similar required)
Suppose, you want to wrap this function:
double foo(double, double);
To wrap it, you simply write:
pyWrapFunction(foo, foo);
where the first argument will become the Python identifier of the
function, while the second is a pointer to the C++ function. In Python,
you would call the function like this:
>>> foo(1.0, 2.0)
Likewise, a class
class Foo
{
public:
Foo();
virtual ~Foo();
virtual int foo_method(int, int);
};
is wrapped as follows:
pyWrapClass(Foo, Foo);
where the first argument is the Python class name, the second the C++
class name. Methods are wrapped similarly to functions:
pyWrapMethod(Foo, bar, &Foo::foo_method);
whith the first two arguments being the Python class and method names,
and the last a pointer to a C++ member function. To wrap constructors,
the argument list is given instead of a function pointer (pointers to
constructors do not exist in C++):
pyWrapDefaultConstructor(Foo, Foo);
We use class Foo in Python like this:
>>> x = Foo()
>>> x.foo_method(1,2);
>>> del x
Inheritance is also supported:
class Bar : public Foo
{};
pyWrapClass(Bar, Bar);
pyDeclareBaseClass(Bar, Foo);
pyWrapDefaultConstructor(Bar, Bar);
Thus, the Python class Bar is declared a subclass of the Python class
Foo - it inherits all methods and is convertible into a base object in
an expression. (This code only compiles iff the C++ class Bar is indeed
a direct or indirect subclass of the C++ class Foo). In Python, we use
Bar like this:
>>> x = Bar()
>>> x.foo_method(1,2); # inherited from Foo
>>> del x
Other features of 'Python<C++>' include support for multiple
inheritance, virtual base classes, abstract classes, translation of C++
exceptions into Python exceptions, mapping of Python tuples (up to 5
members) and (homogeneous) lists onto PyWrapperTuple and
PyWrapperArray.
The module 'cxxmodule.cxx' included in the tar file illustrates some of
these features (sorry, no documentation exists yet). I have successfully
compiled and used the module under Python 1.5, GNU g++ 2.8.0, on a UNIX
machine. The script 'test.py' is provided to test the module. The
expected output is contained in 'testout.txt'. To try:
g++ -fpic -I$PYTHON_INCLUDE -c cxxmodule.cxx -o cxxmodule.o
g++ -shared -o cxxmodule.so cxxmodule.o
python test.py >& out.txt
diff out.txt testout.txt
I hope you enjoy the package. Any comments are very welcome.
Regards, Ulli
--
_____________________________________________________________
| |
| Ullrich Koethe Fraunhofer Institute for Computer Graphics |
| Rostock |
| |
| Phone: +49-381-4024-114 Joachim-Jungius-Str. 9 |
| Fax: +49-381-4024-199 D - 18059 Rostock |
| Email: koethe(a)egd.igd.fhg.de Germany |
|_____________________________________________________________|