I use SWIG and Numpy. I define a C function called inplace() to process data array fast, and I want to make some error checking (if two arrays have the same dimentions).
I use %rename and %inline in the .i file. As I understand, rename should map the function names’, so every time someone uses inplace, safe_inplace is run and the errors are checked.
But it does not work 🙁 . As far I notice, safe_inplace is not executed, python runs directly inplace without touching the safe version of the function.
# .i
%include "inplace.h"
%rename (inplace) safe_inplace;
%inline %{
void safe_inplace(int* datain, int in_dx, int in_dy, int in_dz,
int* dataout, int out_dx, int out_dy)
{
if ((in_dx != out_dx) || (in_dy != out_dy)) {
PyErr_Format(PyExc_ValueError, /*... messgage*/)
return;
}
inplace( /* .. pass the arguments to original function*/ );
}
header file:
# .h
void inplace(int* datain, int in_dx, int in_dy, int in_dz, int* dataout, int out_dx, int out_dy);
Python:
#.py
inplace.inplace(a,b)
The original example that I modify can be found here
Your original approach was close, but you probably want to get SWIG not to wrap the original version of the function at all.
I’ve put together a slightly simpler example illustrating how this could work. Given the header file:
We want to wrap it such that a slightly modified version is called before invoking the real one.
The simplest way to do this would be to never actually show SWIG the header file at all for wrapping, only for compiling the wrapper, e.g.:
If you don’t want to drop the
%include(e.g. there’s other things you care about in that header file too) you can do something like:To expose the real implementation of
fooasunsafe_foo.Or you could use
%ignoreif there’s no reason for Python users to be able to callunsafe_ignoreever:Finally it looks like your goal is actually just to run some code prior to the call of the real C function. If that’s the case there’s a few ways you can do that too, for example you can add python code before the real function call is made with
pythonprepend:Or lastly you could use the
%exceptionfunctionality too, something like (untested):$actionwill be substituted with the real call automatically.