(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.
This is my revised test case here. I haven't yet got it to compile, although it should show very clearly what I'm trying to do.
Can anyone see how to get this technique working, or improve upon it?
Aucun commentaire:
Enregistrer un commentaire