我正在尝试将函数传递给GLUT,回调glutSpecialFunc。
当我尝试将静态函数(specialKeyProcessor)传递给它时,它工作正常。
当我将此函数移动到专门处理键盘相关函数的类(KeyBoardMovement)时,它似乎不起作用:
.... KeyboardMovement键盘; .... glutSpecialFunc(keyboard.specialKeyProcessor);
弹出错误:必须调用对非静态成员函数的引用。
我不明白这个错误,因为我看不到放在不同地方的同一个功能之间有什么区别。
答案 0 :(得分:2)
glutSpecialFunc
函数设置每个窗口的回调。如果您使用的是OpenGLUT,它还允许您使用glutSetWindowData
将某些数据与每个窗口相关联。
因此,你可以创建一个像这样的全局填充函数:
void specialKeyProcessor(int key, int x, int y) {
KeyboardMovement *keyboard = static_cast<KeyboardMovement *>(glutGetWindowData());
keyboard->specialKeyProcessor(key, x, y);
}
并使用glutGetWindowData
关联键盘处理程序:
glutSetWindowData(static_cast<void *>(&keyboard));
如果您需要存储多个窗口数据,则可以存储指向特定于窗口的struct
的指针,其中包含每个窗口特定数据的字段。
如果您不使用OpenGLUT,可以考虑为全局数据创建std::map
映射窗口ID。然后,您可以采用与上述类似的方法来获取特定于窗口的数据。
答案 1 :(得分:0)
C ++不支持闭包,这意味着它不能将类实例与方法一起转换为函数指针,调用时将执行类实例的方法。
不幸的是,GLUT不像大多数其他C回调API那样支持数据感知回调。所以要么编写一个包装函数,它将调用类的全局实例,或者使用一个名为“ffcall”的库来使用一些非常脏的技巧,这些库实际上可以在运行时创建新函数,这些函数可以被参数化并充当你可以传递给GLUT的一个闭包。但那真是黑暗的东西,正确的事情就是放弃GLUT。