繁体   English   中英

使用成员函数作为回调

[英]Use a member function as callback

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

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

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

但是我能做什么呢?

您可以使用glfwSetWindowUserPointer附加一个管理窗口的C ++类。 之后,您可以编写一个静态函数转发到“ WindowManager”的成员函数

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

2.16-如何将C ++方法用作回调?

您不能将常规方法用作回调,因为GLFW是C库,并且不了解对象和此指针。 如果希望接收对C ++对象的回调,请使用静态方法或常规函数作为回调,将指向您要调用的对象的指针存储为窗口的用户指针,并使用它来调用对象上的方法。

您需要传递这种类型的函数指针:

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);
});

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM