我想使用成员函数作为回调(使用this function):
glfwSetCursorPosCallback(window, (GLFWcursorposfun)(MyClass::mouseButtonChanged));
我知道这是不可能的,因为我需要一个MyClass
的实例来调用方法mouseButtonChanged
。
但我该怎么办?
答案 0 :(得分:5)
您可以使用glfwSetWindowUserPointer
附加管理窗口的C ++类。之后,您可以编写一个静态函数转发到'WindowManager'的成员函数
来自http://www.glfw.org/faq.html#how-do-i-use-c-methods-as-callbacks
2.16 - 如何使用C ++方法作为回调?
您不能使用常规方法作为回调,因为GLFW是C库 并且不知道对象和这个指针。如果你愿意的话 接收回调到C ++对象,使用静态方法或常规方法 作为回调函数,将指针存储到您想要的对象 调用窗口的用户指针并使用它来调用方法 你的对象。
答案 1 :(得分:4)
您需要传入此类型的函数指针:
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,因为任何带有捕获的东西都不能转换为函数指针。
[更新]由于您可以在void*
上添加window
,因此您也可以这样做:
glfwSetWindowUserPointer(window, &myObj);
glfwSetCursorPosCallback(window, +[](GLFWindow* win, double a, double b){
static_cast<MyClass*>(glfwGetWindowUserPointer(win))->mouseButtonChanged(win, a, b);
});
没有捕获的lambda上的operator+
(例如本例中的那个)将其转换为原始函数指针。