Callback_12.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Callback_12.cpp : Diese Datei enthält die Funktion "main". Hier beginnt und endet die Ausführung des Programms.
  2. //
  3. #include <iostream>
  4. #include <utility>
  5. #include <iostream>
  6. /**
  7. * Trampolines to methods for C-style callbacks.
  8. *
  9. * The void* / callback data is the instance you want the method
  10. * called on.
  11. */
  12. template<typename T, typename ...Types>
  13. struct trampoline {
  14. /**
  15. * Trampoline for callbacks with void* argument at the end of the
  16. * argument list
  17. */
  18. template<void (T::* ptmf)(Types...)>
  19. static
  20. void postvoid(Types... args, void* object) {
  21. T* o = static_cast<T*>(object);
  22. (o->*ptmf)(std::forward<Types>(args)...);
  23. }
  24. /**
  25. * Trampoline for callbacks with void* as the first argument
  26. */
  27. template<void (T::* ptmf)(Types...)>
  28. static
  29. void prevoid(void* object, Types... args) {
  30. T* o = static_cast<T*>(object);
  31. (o->*ptmf)(std::forward<Types>(args)...);
  32. }
  33. };
  34. void c_style_callback_caller(void (*cb)(int, void*), void* data)
  35. {
  36. cb(42, data);
  37. }
  38. void c_style_callback_caller_pre(void (*cb)(void*, int), void* data)
  39. {
  40. cb(data, 41);
  41. }
  42. class C {
  43. public:
  44. void p0() {
  45. std::cout << "p0()\n";
  46. }
  47. void p1(int x) {
  48. std::cout << "p1(" << x << ")\n";
  49. }
  50. static
  51. void classic_cb_p1(int x, void* object) {
  52. C* c = static_cast<C*>(object);
  53. c->p1(x);
  54. }
  55. };
  56. int main() {
  57. C inst;
  58. // both produce EXACTLY the same code
  59. c_style_callback_caller(trampoline<C, int>::postvoid<&C::p1>, &inst);
  60. c_style_callback_caller(&C::classic_cb_p1, &inst);
  61. // also supports void* as the first argument
  62. c_style_callback_caller_pre(trampoline<C, int>::prevoid<&C::p1>, &inst);
  63. // special case: no parameters on callback means postvoid and
  64. // prevoid are identical
  65. trampoline<C>::postvoid<&C::p0>(&inst);
  66. trampoline<C>::prevoid<&C::p0>(&inst);
  67. return 0;
  68. }