SWIG and functions with error codes and strerror

SWIG is a wrapper generator that is able to connect compiled libraries to a bunch of scripting languages. The process is mostly automatic, but to tackle some corner cases, you have to help the generator do the right thing. In my library, all functions would return an integer, which is an error code. A special function, following the same behavior as strerror_r, can be used to retrieve the meaning of a special error code. This is a pretty usual mechanism for C code. But that’s not the way scripting languages work. In their world, functions are rather supposed to raise exceptions.

If you are familiar with SWIG, you may prefer to skip to the last section.

Example Library

Let’s imagine a small and simple library to serve as an example to the below explanations. It has an init and a do_something functions. Both return a special integer code that indicates whether the call was successful and if not, which error happened. An strerror-like function is available to retrieve a textual description for a given error code. That way, an application using our library can display to its end-user a better explanation of what has gone wrong.

Basic Wrapping with SWIG

In our situation, a direct wrapping of the library will not work. Indeed, as mylib_strerror_r is taking arguments as outputs, we need to instruct SWIG to use them properly. This is done by injecting wrapping code at different positions when the arguments pattern is found.

Note: We could use %new_array and %delete_array to manage the buffer, which would make the piece of code compatible with C++. But these macros do not handle allocation failures (as of 3.0.8).

If we were lazy, the library could be used as it is now. As in C, we would just compare the returned value and do some actions if it doesn’t succeed.

But this is not how a module in expected to work in the world of scripting languages.

Raising Exceptions

What we want to do, is actually map the return value. We want SWIG to check the return value and, if it is 0, return nothing. Else, it shall raise an exception. If possible, we want some code that supports as many languages as possible. Not just Python, for example, so no PyErr_SetString.

Now, the library feels much more at home in the scripting ecosystem.

Featured Image Credits: Marcel Langthim