使用成员函数作为回调

Use a member function as callback

我想使用成员函数作为回调(使用this function):

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

我知道这是不可能的,因为我需要一个 MyClass 的实例来调用方法 mouseButtonChanged

但是我能做什么呢?

你需要传入一个这种类型的函数指针:

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

不幸的是,他们似乎没有为您提供任何类型的上下文参数。所以一种方法是全局回调方法:

struct MyCallback {
    static MyClass* obj;

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

像这样使用:

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

之所以有效,是因为 callback 现在不需要实例。不幸的是,现在我们周围有一个全局 MyClass*。不过,我们有点坚持这一点。我们不能在这里使用 std::bind() 表达式或 lambda,因为任何带有捕获的东西都不能转换为函数指针。

[更新] 因为你可以在 window 上添加一个 void*,你也可以这样做:

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

其中 operator+ 在没有捕获的 lambda 上(例如本例中的那个)将其转换为原始函数指针。

您可以使用 glfwSetWindowUserPointer 附加管理 window 的 C++ class。之后你可以写一个静态函数转发到 'WindowManager'

的成员函数

来自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.