I am wrapping the following C++ code:
// content of cpp.h
class A
{
public:
virtual int fnA() = 0;
virtual ~A() { }
};
class B
{
public:
int fnB(A &a)
{
return a.fnA();
}
};
by SWIG using the SWIG wrapper:
// content of swigmodule.i
%module(directors="1") swigmodule
%feature("director");
%feature("director:except") {
if ($error != NULL) {
fprintf(stderr, "throw\n");
throw Swig::DirectorMethodException();
}
}
%exception {
try { $action }
catch (Swig::DirectorException &e) { fprintf(stderr, "catch\n"); SWIG_fail; }
}
%{
#include "cpp.h"
%}
%include "cpp.h"
where the exception handling is copied from the SWIG manual. Using this I generated the SWIG wrapper with: "swig -c++ -python swigmodule.i; g++ -shared -fPIC -I/usr/include/python2.7 swigmodule_wrap.cxx -o _swigmodule.so"
The problem now comes when incorrectly overloading the "int fnA()" function with a "void fnA()" in Python.
# content of useit.py
from swigmodule import A, B
class myA(A):
def fnA(self):
print("myA::fnA")
b = B();
a = myA();
print("%d"% b.fnB(a) )
The generated SWIG wrapper correctly flags this at runtime as an error; fnA(self) returns None which is not an int. However, the output at the console is:
$ python useit.py
myA::fnA
catch
Traceback (most recent call last):
File "useit.py", line 12, in <module>
print("%d"% b.fnB(a) )
File "/home/schuttek/tmp/swigmodule.py", line 109, in fnB
def fnB(self, *args): return _swigmodule.B_fnB(self, *args)
TypeError: SWIG director type mismatch in output value of type 'int'
which is misleading as it suggests that the error is in B::fnB where the actual error is in overloading A::fnA.
How do I get SWIG to provide a meaningfull diagnostic to where the error occured? In my real code (this is a simplified version) I had to use GDB to trap on the constructor of the Swig::DirectorException class. This is unwanted as the actual error was in the Python domain (where an incorrect overlaod was performed) and I want to shield future Python users from GDB and its usage, as well as from a SWIG internal such as a DirectorException.