简体   繁体   English

使用成员函数作为回调

[英]Use a member function as callback

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 . 我知道这是不可能的,因为我需要一个MyClass实例来调用方法mouseButtonChanged

But what can I do? 但是我能做什么呢?

You might use glfwSetWindowUserPointer to attach a C++ class managing the window. 您可以使用glfwSetWindowUserPointer附加一个管理窗口的C ++类。 After that you can write a static function forwarding to to a member function of the 'WindowManager' 之后,您可以编写一个静态函数转发到“ WindowManager”的成员函数

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

2.16 - How do I use C++ methods as callbacks? 2.16-如何将C ++方法用作回调?

You cannot use regular methods as callbacks, as GLFW is a C library and doesn't know about objects and this pointers. 您不能将常规方法用作回调,因为GLFW是C库,并且不了解对象和此指针。 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. 如果希望接收对C ++对象的回调,请使用静态方法或常规函数作为回调,将指向您要调用的对象的指针存储为窗口的用户指针,并使用它来调用对象上的方法。

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. 之所以可行,是因为callback现在不需要实例。 Unfortunately, now we have a global MyClass* lying around. 不幸的是,现在我们有了一个遍布全球的MyClass* 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. 我们在这里不能使用std::bind()表达式或lambda,因为任何带有捕获的内容都无法转换为函数指针。

[update] Since you can add a void* onto the window , you can also do this: [更新]由于您可以在window上添加一个void* ,因此您也可以这样做:

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. 没有捕获的lambda上的operator+ (例如本例中的那个)将其转换为原始函数指针。

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

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