EDIT: I think I hacked it, here
(Non bijective here means that we can have arguments like const char or char * both mappings in const std :: string &.) *
NOTE. I am working on this and asking similar questions for several days. Nevertheless, I will present the resume from scratch, as this can make the question a worthy resource.
I have a C function pointer:
R_c (*CFunc)( void* self, A1, A2, ..., Ak ) CFunc slot = nullptr;
And its associated C ++ method:
class Base { R_cxx f_cxx( X1, X2, ..., Xk ); }
I need to create a mechanism that forwards.
The C library will call say x = slot(&someobject, 1, "two") , and my task is to create a slot function that will use 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 that I have about 100 different slots, covering perhaps 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, this is a semi-pseudo-code. Actually, the syntax is much more complicated, since you need to pass decltype(foofunc), foofunc to the template - just foofunc not foofunc (although there is a chance that this will be fixed in C ++ 17). An intermediate level of the template is also needed to separate the function signature into returntype, C ++ base and args. And the function toCXX (T t) must be overloaded to map all the necessary A_k to X_k.
I thought yesterday this crack cracked thanks to this answer .
The solution was to create a C function signature from the f_cxx signature. However, since then, I realized that this approach will not work for one unfortunate reason: two different types of C for the same type of C ++.
i.e. The slot function may have a signature with const char* and char* . But both of them are mapped to 'const std :: string &'. Thus, this technique will not work when it encounters "const std :: string & --it does not know whether to go back to char* or const char* .
Therefore, I am trying 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 afraid.