This is how I do it. block% {...%} inserts its contents into the wrapper file. The% exception block excludes the SWIG exception handling and starts after each function call to check if there was an error, and threw an exception with PyErr_SetString, if any. Then just call "set_err" ("Error msg"), from your C function, if you want to throw an exception.
%{ static int swig_c_error_num = 0; static char swig_c_err_msg[256]; const char *err_occurred() { if (swig_c_error_num) { swig_c_error_num = 0; return (const char*)swig_c_err_msg; } return NULL; } void set_err(const char *msg) { swig_c_error_num = 1; strncpy(swig_c_err_msg, msg, 256); } %} %exception { const char *err; $action if (err = err_occurred()) { PyErr_SetString(PyExc_RuntimeError, err); return NULL; } }
Alternatively, if your C library uses a standard set of return codes, you can replace this mechanism by checking the function return code in the% exception block.
%exception { int rc; rc = $action; if (rc == ERR) { PyErr_SetString(PyExc_RuntimeError, <err msg>); return NULL; } }
source share