Search code examples
c++callbackthis-pointer

Send this instance as callback parameter


I have simple UI class and I need to send UI element instance to callbacks for each element, so I can (much like in javascript) manipulate element which called the callback.
This requires to send instance of this to the function registered as callback. How do I do that?
Current state:

class Opencv_Button {
private:
    bool (*callback)(void*);                 //Callback WITHOUT the current button isntance
    //bool(*callback)(Opencv_Button, void*); //this is CALLBACK I WANT instead
    void* callback_param;                    //parameter set by user
    bool state;
    bool mouse(int, int, int);
public:
    Opencv_Button(int, int, int, int);
    void setCallback(bool(*)(void*), void*);
    //void setCallback(bool(*)(Opencv_Button, void*), void*);  //This is what I WANT TO USE
    void draw(Mat*, bool);
    void val(const char*);
    char value[30];
};

Now, there is the function that calls the callback:

bool Opencv_Button::mouse(int mx, int my, int button) 
{
    if(/*click conditions satisfied*/) 
        {
             /*CLICK!!!*/
                  if(callback!=0)
                     callback(callback_param);
                     /*Instead I WANT:*/
                     //callback(*this/*some THIS instance*/, callback_param);
                 return true;
        }
    return false;
}

So, I can do something like this in callback:

bool buttonCallback(Opencv_Button*but, void*param) {
     but->val("I was clicked!!!");
}

Solution

  • You're pretty close. The quick fix is to make sure your callback takes a pointer and you pass this:

    bool (*callback)(Opencv_Button*, void*);
    void setCallback(bool(*)(Opencv_Button*, void*), void*);
    

    And call with:

    callback(this, callback_param);
    

    However, you'd likely be better off using references. You can have your function take a reference to Opencv_Button:

    bool (*callback)(Opencv_Button&, void*);
    void setCallback(bool(*)(Opencv_Button&, void*), void*);
    

    Then call it with:

    callback(*this, callback_param);
    

    And your buttonCallback will look like this:

    bool buttonCallback(Opencv_Button& but, void* param) {
      but.val("I was clicked!!!");
    }