fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. #include <map>
  5.  
  6. template<typename T>
  7. class Base
  8. {
  9. public:
  10. //typedef void (T::*PFunc)(void);
  11. //typedef void (*PHandler)(void*);
  12. using PFunc = void (T::*)(void);
  13. using PHandler = void(*)(void*);
  14. using method_map_t = map< string, PHandler >;
  15.  
  16. static method_map_t& methods( ) {
  17. static method_map_t* map_of_methods{};
  18. if( ! map_of_methods ) map_of_methods = new method_map_t;
  19. return *map_of_methods;
  20. }
  21.  
  22. template<PFunc func>
  23. static void register_method( string name ) {
  24. methods()[name] = &Handler<func>;
  25. }
  26.  
  27. // generic trampoline
  28. template<PFunc func>
  29. static void Handler( void* pInstance ) {
  30. T* f = reinterpret_cast<T*>(pInstance);
  31. (f ->* func)();
  32. }
  33. };
  34.  
  35. class Final : Base<Final>
  36. {
  37. public:
  38. void Foo(){ cout << "got foo" << endl; }
  39. void Bar(){ cout << "got bar" << endl; }
  40.  
  41. static void init(){
  42. // register_method populates a table of "extern C" function pointers.
  43. register_method<&Final::Foo>( "foo" ); //, static_cast<PHandler>( &Handler<&Final::Foo> ) );
  44. register_method<&Final::Bar>( "bar" ); //, static_cast<PHandler>( &Handler<&Final::Bar> ) );
  45. }
  46. };
  47.  
  48. void InvokeFromC(void* inst, string name) {
  49. Base<Final>::PHandler h = Base<Final>::methods()[name];
  50. (*h)(inst);
  51. }
  52.  
  53. int main() {
  54. Final* f = new Final{};
  55. f->init();
  56. // simulate invoking from C
  57. InvokeFromC( f, "foo" );
  58. InvokeFromC( f, "bar" );
  59.  
  60. // your code goes here
  61. return 0;
  62. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
got foo
got bar