I’ve got some C code that I want to expose to Python. It has a calling convention like this:
int add(int a, int b, int *err)
where the return value would be (a+b) or whatever, but if something went wrong, then I would get an error code in *err. I want to wrap this function so that it behaves like this, from the Python perspective:
def add(a,b):
if something_bad:
raise RuntimeError("something bad")
return a+b
This should be easy, right? But I’m not finding it so.
Here is something that I have that works, but look out for the myerr3 kludge:
%module myswig
%feature("autodoc","1");
%{
int add(int a, int b, int *err){
if(a < 0)*err = 1;
if(b < 0)*err = 2;
return a+b;
}
char *err_string(int err){
switch(err){
case 1:return "first argument was less than 0";
case 2:return "second argument was less than 0";
default:return "unknown error";
}
}
%}
%typemap(in,numinputs=0) int *err (int myerr = 0){
$1 = &myerr;
};
%exception{
$action
if(myerr3 != 0){
PyErr_SetString(PyExc_RuntimeError,err_string(myerr3));
return NULL;
}
};
int add(int a, int b, int *err);
This behaves as it should, eg with
import myswig
print "add(1,1) = "
print myswig.add(1,1)
# prints '2'
print "add(1,-1) = "
print myswig.add(1,-1)
# raises an exception
# we never get here...
print "here we are"
but I can’t really use this solution, because if I have another function like
int add(int a, int b, int c, int *err)
then my myerr3 kludge will break down.
What’s the better way to solve this problem, without changing the calling convention of the C code?
From Karl Wette, via the swig-user mailing list:
This seems to be exactly the right solution, no kludges required. Thanks Karl!