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