I'm trying to recode some rather ugly template coding.
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
class Final : Base
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & FooHandler );
register_method( "bar", & BarHandler );
}
:
// trampolines
static void FooHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Foo();
}
static void BarHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Bar();
}
}
My code interfaces with CPython (C library). Python runtime sees "myInst.foo" , looks up "foo" in table and invokes:
Final::FooHandler( pointer_to_myInst );
(Note it is possible to typecast a static method to a C function pointer)
FooHandler trampolines to the Foo method of the correct instance of Final.
In reality, the handle is not so clean, and there are many methods each of which requires an identical handler (but with a distinct function address).
I am attempting to abstract the handler mechanism into a base class, something like this:
class Final : Base<Final>
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & Foo, Handler< &Foo> );
register_method( "bar", & Bar, Handler< &Bar> );
}
:
}
class Base<Final>
{
typedef void (Final::*FuncSig)(void);
typedef void (Final::*HandlerSig)(void*); // takes 1 pvoid param
void register_method( std::string name, FuncSig meth, HandlerSig handler ) {
...
}
// generic trampoline
template< Sig sig>
static void Handler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f ->* sig();
}
}
I'm currently getting stuck in compiler errors (http://ideone.com/vOtbcD), so I'm not even sure whether the technique is valid.
Is there some way to do this, or is this just one of those times where you really need macros?
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
As can be seen, the original uses rather ugly macros.
register_method
needs to be static if you're going to call it from the staticinit
function.Calling a member function through a member function pointer requires an additional set of parenthesis:
(f->*sig)();
With those in place, your test case compiles in C++11 mode. That said, have you considered using
std::function
andstd::bind
to do this instead? Hard to tell what that would actually look like without knowing whatregister_method
does, but it might wind up a bit cleaner.