EDIT: I think I have cracked it, here
(Non bijective here means we may have arguments of type const char or char* both mapping to const std::string&.)*
NOTE: I've been working at this and asking similar questions for a few days now. Nevertheless, I will present a summary from scratch, as it may make the question a decent resource.
I have a C function pointer:
R_c (*CFunc)( void* self, A1, A2, ..., Ak )
CFunc slot = nullptr;
And an associated C++ method:
class Base {
R_cxx f_cxx( X1, X2, ..., Xk );
}
I need to create a mechanism that forwards.
The C Library is going to invoke say x = slot(&someobject, 1, "two")
, and my task is to create a slot
function that will trampoline to:
slot( void* self, A1 a1, A2 a2 ) {
R_cxx ret = ((Base*)self)->f_cxx( toCxx<A1>(a1), toCXX<A2>(a2) );
return toC<R_cxx>(ret);
}
The problem is I have close to 100 different slots, spanning maybe 20 different signatures. So I need to automate this.
I would start with a template containing a static function:
template< typename F_c, typename F_Cxx >
struct Generator {
static Bla call( etc ) {...}
};
#define BIND_SLOT( F_c, F_Cxx ) &Generator<F_c,F_Cxx>::call
:
BIND_SLOT( table->slot35, Base::handler_35 );
Of course, that is semi-pseudocode. Actually the syntax is much more complicated, as you need to pass decltype(foofunc), foofunc
into a template -- just foofunc
alone is not sufficient (although there is some chance this will be fixed in C++17). Also an intermediate template layer is necessary for splitting a function signature into returntype, C++base and args. And a toCXX(T t) function would need to be overloaded to map all necessary A_k to X_k.
I thought I had this cracked yesterday thanks to this answer.
The solution was to construct the C function signature from f_cxx's signature. However I have since realised that this approach won't work for one annoying reason: Two different C-types map onto the same C++ type.
i.e. The slot-function may have a signature involving const char*
and char*
. But both of these get mapped onto 'const std::string&'. So that technique would fail the moment it comes across 'const std::string&' --it doesn't know whether to convert back to char*
or const char*
.
Hence I'm attempting to rewrite it, this time using the signature of the slot function, instead of the cxx member function.
However, this is extremely complex code, and I'm struggling.