Statically Typed

because Hindley-Milner rocks

Swig, Python and C++ Exceptions (cont’)

Greater success today with implementing exception passing between Python and C++.  Learned a few gotchas, used a tip from SO, and generally all around excited to continue with the project full steam ahead!  Sounds like a good day, no?  It was.

Python -> C++

I was having the hardest time getting the C++ code to recognize hand crafted exception classes as I said below.  They kept being converted to Swig::DirectorMethodException.  However, following a tip I made a C++ class especially for throwing C++ exceptions in C++.

struct ExceptionFactory{
    void throwAlarm() const { throw Alarm(); }
    void throwNormal() const { throw std::exception(); }
    void throwTilde() const { throw int(4); }

And at the Python level I implemented my Foo class as

class FooRedux(Foo):
    def __init__(self):
    def getInt(self):
        return 6
    def throw(self):

which did the trick for our own declared C++ exceptions.  (Update:  This won’t work.)

Next up was getting the C++ code to recognize Python exceptions.  This couldn’t be easier.  Someone had already thought of it and added the functionality to SWIG.  It involved inserting a small amount of code into the *.i file.

    ( $error != NULL ){
        throw Swig::DirectorMethodException();

Bingo, done.

C++ -> Python

Getting Python to recognize our own home grown exceptions came with a small surprise.  First we had to put in more code into the *.i file to tell SWIG how to communicate back to the Python code.

    catch( Alarm &ex ){
        PyErr_SetString( PyExc_RuntimeError, ex.msg() );
    catch( std::exception &ex ){
        PyErr_SetString( PyExc_RuntimeError, ex.what() );
    catch( Swig::DirectorException ){
        PyErr_SetString( PyExc_RuntimeError, "Swig::DirectorException thrown" );
    catch( ... ){
%include exception.i

Looks verbose but worth the trouble.  Once we fired up IDLE we had to make sure to do one more thing… not import Alarm!  That’s right, I had to specifically import every object I wanted to use except for my own defined exception.  If it was imported, it caused a crash the minute the C++ code attempted to throw it.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


This entry was posted on May 26, 2010 by in Uncategorized.
%d bloggers like this: