0

EDIT: (September 26th)

For a touchScreen calibration tool I have a MT_Interface class that has a memberfuntion Send_Touch_Event. Every time This function is called I want to run a callback function called "EventWrite" from a different class ( Calibration_checker).

In the code, these are the following functions that are of interest (I think, I did not make MT_Interface).

class MT_Interface 
{
          void SetCallback( void (*cb)(MT_Interface_TouchEvent_Type), void* o ) {Callback_fct = cb; Callback_obj = o;};
          void Send_Touch_Event(MT_Interface_Message_Type Message, int ID, int X, int Y, int Additional_Info1, int Additional_Info2);
          {
            // Does something and than uses the callback
               (*Callback_fct)(touch_event, Callback_obj);
          };
}

The class with the function EventWrite can be summarized as:

class Calibration_checker 
{

    MT_Interface *MT_Interface_object  

    EventWrite(MT_Interface_TouchEvent_Type t, void* o)

    Configure()
    {
     // Configure the MT_Interface_object & set callback    
     MT_Interface_object->SetCallback(&Calibration_checker::EventWrite, (void*)this);
     }
}

I think the SetCallBack function is to be used here, though I can't get it to work. I do not quite understand the error message I get. Maybe someone here can get shed light on the issue?

when I apply a wrapper function as proposed below I get similar errors, unfortunately.

Calibration_checker.cxx: In member function ‘void Calibration_checker::Configure()’:
Calibration_checker.cxx:83:81: error: no matching function for call to ‘MT_Interface::SetCallback(void (Calibration_checker::*)(MT_Interface_TouchEvent_Type, void*), void*)’
   MT_Interface_object->SetCallback(&Calibration_checker::EventWrite, (void*)this);
                                                                                 ^
In file included from Calibration_checker.hxx:4:0,
                 from Calibration_checker.cxx:4:
MT_Interface.hxx:163:12: note: candidate: void MT_Interface::SetCallback(void (*)(MT_Interface_TouchEvent_Type, void*), void*)
       void SetCallback( void (*cb)(MT_Interface_TouchEvent_Type, void*), void* o ) {Callback_fct = cb; Callback_obj = o;};
            ^
MT_Interface.hxx:163:12: note:   no known conversion for argument 1 from ‘void (Calibration_checker::*)(MT_Interface_TouchEvent_Type, void*)’ to ‘void (*)(MT_Interface_TouchEvent_Type, void*)’
Simon
  • 57
  • 1
  • 7
  • Can you create a lambda and pass it as a callback? Then you can capture anything there and execute any code you want. – Rinat Veliakhmedov Sep 25 '17 at 13:35
  • In short: pointer to function is not enough, you must pass reference/pointer to object as well (in explicit way as parameter or via functor object) From related list: https://stackoverflow.com/questions/2298242/callback-functions-in-c?rq=1 – R2RT Sep 25 '17 at 13:40

1 Answers1

0

Non-static member functions cannot exist as function pointers, because the this pointer needs to be conveyed somehow. Thankfully, it looks like the o argument gets passed back to the callback function, so passing the object as the second parameter and a wrapper function as the first parameter should do the trick.

Given this type:

struct Foo
{
    void EventWrite(MT_Interface_TouchEvent_Type);
};

And this wrapper function:

void foo_touch_event_wrapper(MT_Interface_TouchEvent_Type t, void *o)
{
    static_cast<Foo *>(o)->EventWrite(t);
}

And some instance foo that will still exist when the callback is invoked, then we can attach the handler:

someObject.SetCallback(foo_touch_event_wrapper, &foo);
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • Thank you for your suggestion. I don't get why you use the *o argument. In the original code there was a SetCallback function for a different purpose (assuming a already calibrated touchscreen): where the void pointer o was used to access member variables (calibration coefficients) defined in another class. In this case I do not need this argument (I think), as I only want to use the _MT_Interface_TouchEvent_Type_ output. Because of this I do not really know how to apply the wrapper option. – Simon Sep 25 '17 at 14:06
  • @Simon But `EventWrite` is a member function of a class, correct? If so, we are using the `o` argument to pass *the object on which to invoke `EventWrite`*. – cdhowie Sep 25 '17 at 14:24
  • Eventwrite is unfortunately not a memberfunction of a class. All I need EventWrite to do is to extract the X and Y positions and add them to a variable (which is later averaged to obtain better calibration for a given point on the screen). I could make a Calibration class for it, though. Will check if this works out :) – Simon Sep 25 '17 at 15:06
  • 1
    @Simon Then I actually have no idea at all what your question is asking, and the title ("Callback function for member function") is not just misleading but completely wrong. Please edit your question to include a clear question / problem statement. – cdhowie Sep 25 '17 at 15:08
  • I will edit the title, though my post should be clear as is if I'm not mistaken. "How do you use a 'normal'/non-member function as a callback for a member function of a class (MT_Interface in this case)?" – Simon Sep 25 '17 at 15:23
  • @Simon I can't even grok that sentence. I don't know what it is asking. – cdhowie Sep 25 '17 at 15:26
  • I have changed my code to implement the EventWrite function in a class, such that I could apply the wrapper option (Edited my question to clearify this). I get an error message very similar to the one I included in my edit. It is an invalid conversion, though I don't quire understand the error source. Could you perhaps shed light on this issue? – Simon Sep 26 '17 at 11:03
  • @Simon It's exactly what I said in my answer: *"Non-static member functions cannot exist as function pointers."* `&Calibration_checker::EventWrite` is a pointer-to-member-function, but `void (*)(MT_Interface_TouchEvent_Type, void*)` is a pointer-to-function. These types are incompatible. That's why you need a wrapper function to do the member invocation (`foo_touch_event_wrapper` in my example). – cdhowie Sep 26 '17 at 13:37