Passing in C++ Method as a Function Pointer?

后端 未结 2 471
深忆病人
深忆病人 2021-01-27 06:09

I\'ve created a class called InputControl. I am using a library called GLFW, and a function glfwSetKeyCallback. The function is defined as:

GLFWkeyfun glf

相关标签:
2条回答
  • 2021-01-27 06:57

    You could have an interface that calls your member function:

    class App {
    public:
        void onKeyDown(int key, int action) {
            if (action == 1)
                std::cout << "Pressed: " << static_cast<char>(key) << '\n';
            if (action == 0)
                std::cout << "Released: " << static_cast<char>(key) << '\n';
        }
    };
    
    class Interface {
    public:
        static void* p;
    
        static void OnKeyDown(GLFWwindow * window, int key, int scancode, int action, int mods) {
            ((App*)(p))->onKeyDown(key, action);
        }
    };
    void * Interface::p;
    
    int main()
    {
        App app;
    
        [...]
    
        glfwSetKeyCallback(window, Interface::OnKeyDown);
    
    }
    
    0 讨论(0)
  • 2021-01-27 07:07

    A non-static member function needs an object to work on. You need a non-member function, or a static member function, as the callback. If you absolutely need to access an instance of your InputControl class inside the callback, you can set the window's user pointer using glfwSetWindowUserPointer(), and then the callback can use that pointer to call a non-static member function:

    class InputControl {
    public:
        void bind();
        void unbind();
    
    private:
         static void keyCallbackStatic(GLFWwindow* window,
                                       int key,
                                       int scancode,
                                       int action,
                                       int mods);
         void keyCallback(GLFWwindow* window,
                          int key,
                          int scancode,
                          int action,
                          int mods);
    };
    
    void InputControl::bind() {
        glfwSetWindowUserPointer(applicationWindow, this);
        glfwSetKeyCallback(applicationWindow, keyCallbackStatic);
    }
    
    void InputControl::keyCallbackStatic(GLFWwindow* window,
                                         int key,
                                         int scancode,
                                         int action,
                                         int mods)
    {
        InputControl* that = static_cast<InputControl*>(glfwGetWindowUserPointer(window));
        that->keyCallback(window, key, scancode, action, mods);
    }
    
    void InputControl::keyCallback(GLFWwindow* window,
                                   int key,
                                   int scancode,
                                   int action,
                                   int mods)
    {
        // Do whatever
    }
    

    It's up to you to make sure your InputControl object stays alive for as long as your window, and that nothing else sets the window's user pointer to anything besides the InputControl object pointer.

    0 讨论(0)
提交回复
热议问题