Motivation

CS has python wrappers, right, but what happens if you make your own plugins
in an external source tree and want to have that accessible from python? This document tries to cover how you can achieve this and much more :)

Introduction

First, you must understand the basics:

You will need to generate a wrapper python module that understands your code.

Now, lets go through these lines (almost) one by one and explain them:

%module pycsextra

This is just a declaration about your package name, also informs swig this is the main .i file for a package.

%import "bindings/cspace.i"

This makes your package "know" all the types and mappings in cs python wrappers. Its useful in case your package deals with cs stuff like csVector3, or in case you inheriting from cs classes.

%{
#include "crystalspace.h"
#include "include/qtwin.h"
%}

Here, the lines between the brackets with percent symbol, go directly into the output cpp code generated by swig. Note you really have to explicitly add in this list any necessary headers, as otherwise swig wont add them itself, and generated code wont compile.

This is the actual place where swig is informed about our own types. We can use %include for each .h file we need to wrap.

The interface_pre and interface_post directives, are there to add special scf wrapping stuff, so that you can query your interfaces from python. Also adds mappings to handle correctly csPtr, csRef and similar for your interface. Note you should only use these on interfaces actually inheriting from ibase.

Ok! This is it.

run swig on this file for creating the correct cpp file

If you have a jam based build system, you can simply copy the jam files from csextra for your own project, otherwise, you can run swig yourself with a command similar to this one:

Note 'cs_csextra.cpp' will be the generated code, 'pycsextra.i' is your input interface files, and the extra options for doing python wrappers, handling cpp and so on. If you are curious there is lots of interesting options for swig :)

compile the module

Again, if using jam compile system, adapting the files from pycsextra module should suffice. If using msvc, you can probably look somewhere how to compile the cpp and link it to python and crystalspace.

Appendices

The plugins/pycsextra/csextramod.cpp file

You might have noticed in cs python modules there is one extra file exporting an special function, something like:

Interestingly enough, this is not really needed, but maybe you have to cope with it, i will explain the situation: the file is made to export an init_<modulename> function to the dll, this is already done by swig, but cs build system mangles this to look like SWIG_init_<modulename>. This is done like this so you can call the function yourself, but should not really be needed and hopefully will be removed soon. Meanwhile, be prepared to deal with this.

Declaring scfImplementation<>

Many times, constructis like this are used in cs classes:

class csPath : public scfImplementation1<csPath, iPath>

This is not a big problem to swig, but it wont wrap the template unless you explicitly declare it with a special directive. If you dont wrap it, the result is swig won't know about the inheritance here, so you loose the inherited functions or interface in the wrapper (so for example you wouldn't be able to use an csPath in the place where an iPath is required).

Dealing with this is simple enough, add the following to the swig file:

%template(scfPath) scfImplementation1<csPath,iPath >;

This basically tells swig what name to use for the templated class (only thing swig needs, really, and this is because the template notation is incompatible with most scripting languages).

Far and away

For more information, read swig manuals, look at cs, cel, csextra, csexternal swig files. They cover a lot of curious situations and can help you to learn more.