Use a member function as callback

放肆的年华 提交于 2019-12-31 05:47:06

问题


I would like to use a member function as a callback (using this function):

glfwSetCursorPosCallback(window, (GLFWcursorposfun)(MyClass::mouseButtonChanged));

I know it is not possible since I need an instance of MyClass to call the method mouseButtonChanged.

But what can I do?


回答1:


You might use glfwSetWindowUserPointer to attach a C++ class managing the window. After that you can write a static function forwarding to to a member function of the 'WindowManager'

From http://www.glfw.org/faq.html#how-do-i-use-c-methods-as-callbacks

2.16 - 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 as the user pointer for the window and use it to call methods on your object.




回答2:


You need to pass in a function pointer of this type:

void (*)(GLFWindow*, double, double)

Unfortunately, it doesn't look like they give you a spot for any kind of context argument. So one approach is the global callback approach:

struct MyCallback {
    static MyClass* obj;

    static void callback(GLFWindow* window, double a, double b) {
        obj->mouseButtonChanged(window, double a, double b);
    }
};

To be used like:

MyCallback::obj = &myObj;
glfwSetCursorPosCallback(window, &MyCallback::callback);

That works because callback now does not require an instance. Unfortunately, now we have a global MyClass* lying around. We're kind of stuck with that though. We can't use a std::bind() expression or a lambda here because anything with a capture won't be convertible to a function pointer.

[update] Since you can add a void* onto the window, you can also do this:

glfwSetWindowUserPointer(window, &myObj);
glfwSetCursorPosCallback(window, +[](GLFWindow* win, double a, double b){
    static_cast<MyClass*>(glfwGetWindowUserPointer(win))->mouseButtonChanged(win, a, b);
});

Where operator+ on a lambda with no capture (such as the one in this case) converts it to a raw function pointer.



来源:https://stackoverflow.com/questions/28283724/use-a-member-function-as-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!