This question follows from here. However, the previous question was worded so badly (wrongly in fact) that it was suggested I ask again from scratch.
I have a table of C-function pointers.
Some C code (let us call it lib-X) has a basic building block (let's call it a X-object). Each X-object can invoke functions on this table.
These table functions generally have different signatures (see typedefs here), although it is possible for several functions to share the same signature. There are about 100 of these functions in the table.
In C++ I have an associated Final:Base class for each X-object.
And I want to forward these calls to the X-object's corresponding C++ Final instance, but I want to enclose this within try/catch, as the C++ consumer may provide a buggy Final.
So I have a C++ Base class that has a virtual function for each entry on the table.
I then have a C++ Final class (possibly many; Final1 Final2 Final3 etc) that derives from the base class.
So now I just need to write a handler that
Gets the first 'self' parameter (which will always be a pointer to the X-object that invoked the function)
Retrieves the associated C++ base class instance.
Within a try catch block, invokes the corresponding virtual function, forwarding all the remaining parameters through,
... which will actually invoke the override in Final.
It's a bit like trying to understand the plot for Inception. lib-X is in fact the Python runtime, although I'm trying to keep things general.
The thing is there are dozens of these functions, and this makes for some very messy and unmaintainable C++ code -- if I have to manually write a trampoline function for each one, looking like:
extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
{
try
{
PythonExtensionBase *p = getPythonExtensionBase( self );
if( kw != NULL )
return new_reference_to( p->call( Object(args), :Object(kw) ) );
else
return new_reference_to( p->call( Object(args), Object() ) );
}
catch( Py::Exception & )
{
return NULL; // indicate error
}
}
(source here)
I'm trying to come up with a compact design that allows this exception-safe trampolining.
My current progress is [REMOVED, see answer below]