Pointing to a function that is a class member - glfw setKeycallback

前端 未结 7 1247
遇见更好的自我
遇见更好的自我 2020-12-02 11:27

I\'m writing a glfw app, in which I\'ve wrapped the function callse into a simple class. Im having trouble setting the key callback. My class is defined as:

         


        
7条回答
  •  北荒
    北荒 (楼主)
    2020-12-02 11:57

    I also ran into this problem with another glfw callback function, but I didn't want to declare my class method as static, because I needed to access the member variables within. So I tried std::function and std::bind for giving me the ability to bind an instance method as the callback function, but unfortunately it's not an option when working with C callbacks.

    The answer to this problem is also stated in the GLFW FAQ "How do I use C++ methods as callbacks":

    You cannot use regular methods as callbacks, as GLFW is a C library and doesn’t know about objects and this pointers. If you wish to receive callbacks to a C++ object, use static methods or regular functions as callbacks, store the pointer to the object you wish to call in some location reachable from the callbacks and use it to call methods on your object.

    However, this encouraged me to apply the Singleton pattern for my callback class and integrate it as following:

    • the callback method of my class is still static, so it can be specified/used as glfw callback
    • this static callback method makes use of the singleton and passes the callback parameters to an instance method
    • this instance method actually handles the callback parameters, with the benefit of being able to access the member variables

    This is what it looks like:

    // Input.h (the actual callback class for glfwSetMouseButtonCallback)
    class Input 
    {
    public:
        static Input& getInstance() // Singleton is accessed via getInstance()
        {
            static Input instance; // lazy singleton, instantiated on first use
            return instance;
        }
    
        static void mouseButtonCallback(int key, int action) // this method is specified as glfw callback
        {
            //here we access the instance via the singleton pattern and forward the callback to the instance method
            getInstance().mouseButtonCallbackImpl(key, action); 
        }
    
        void mouseButtonCallbackImpl(int key, int action) //this is the actual implementation of the callback method
        {
            //the callback is handled in this instance method           
            //... [CODE here]
        }
    
    private:
        Input(void) // private constructor necessary to allow only 1 instance
        {
        }
    
        Input(Input const&); // prevent copies
        void operator=(Input const&); // prevent assignments
    };
    

    and in my main.cpp:

    Input &hexmap = Input::getInstance(); // initialize the singleton
    
    //The glfw callback is set up as follows:   
    glfwSetMouseButtonCallback( &Input::mouseButtonCallback); // specifying the static callback method, which internally forwards it to the instance method
    

提交回复
热议问题