Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
允许静态函数访问数据,而不将数据作为参数传递 我在我的C++应用程序中使用GLFW作为窗口,我尝试使用GLFW的回调来获取输入事件。例如,这是获取关键事件的方式: void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){ // Do something with event data. } int main(){ // initialize window (I have no problems with this step) glfwSetKeyCallback(window, key_callback); // Now when a key is pressed in the window it will call this function. }_C++_Callback_Global Variables_Static Methods_Glfw - Fatal编程技术网

允许静态函数访问数据,而不将数据作为参数传递 我在我的C++应用程序中使用GLFW作为窗口,我尝试使用GLFW的回调来获取输入事件。例如,这是获取关键事件的方式: void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){ // Do something with event data. } int main(){ // initialize window (I have no problems with this step) glfwSetKeyCallback(window, key_callback); // Now when a key is pressed in the window it will call this function. }

允许静态函数访问数据,而不将数据作为参数传递 我在我的C++应用程序中使用GLFW作为窗口,我尝试使用GLFW的回调来获取输入事件。例如,这是获取关键事件的方式: void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){ // Do something with event data. } int main(){ // initialize window (I have no problems with this step) glfwSetKeyCallback(window, key_callback); // Now when a key is pressed in the window it will call this function. },c++,callback,global-variables,static-methods,glfw,C++,Callback,Global Variables,Static Methods,Glfw,问题: 在我的key\u回调中,我想使用在key\u回调函数之外声明的变量,因为我无法更改key\u回调的参数,所以我无法传递对该变量的引用 现在,在上面给出的示例中,我可以简单地在int main()之外声明我的变量,key\u callback和int main()都可以访问该变量的同一实例 我想要的用途: 我想要一个WindowWrapper类来创建和管理glfwWindow的生命周期,这将包括设置事件回调 WindowWrapper.h // Includes class WindowW

问题:

在我的
key\u回调
中,我想使用在
key\u回调
函数之外声明的变量,因为我无法更改
key\u回调
的参数,所以我无法传递对该变量的引用

现在,在上面给出的示例中,我可以简单地在
int main()
之外声明我的变量,
key\u callback
int main()
都可以访问该变量的同一实例

我想要的用途:

我想要一个
WindowWrapper
类来创建和管理
glfwWindow
的生命周期,这将包括设置事件回调

WindowWrapper.h

// Includes
class WindowWrapper{
private:
    Centrum* g_centrum_;
    GLFWwindow* window_;
    std::thread thread_;
public:
    WindowWrapper();
    WindowWrapper(Centrum* g_centrum);
    ~WindowWrapper();
private:
    // Callbacks
    static void key_callback(
        GLFWwindow* window, int key, int scancode, int action, int mods
        );
};
WindowWrapper.cpp

WindowWrapper::WindowWrapper(Centrum* g_centrum){
    g_centrum_ = g_centrum;
    // Initialize window

    glfwSetKeyCallback(window_, key_callback); // Problems

    // Window loop and OpenGL stuff
}
WindowWrapper::~WindowWrapper(){
    thread_.join(); // Don't worry about this, it works but, I will make it safer.
    glfwDestroyWindow(window_);
    printf("WindowWrapper Completely Destructed!\n"); // For testing purposes
}

void WindowWrapper::key_callback(
    GLFWwindow* window, int key, int scancode, int action, int mods
    ){
    // This function is declared static in the class declaration.
    // And as a result I cannot use g_centrum_ since it is a non-static variable
    // Essentially I want to be able to access g_centrum_ from this function
    g_centrum_->input_eventmanager_->key_eventmanager_->
        TriggerKeyEvent(key, action, mods);
}
我想到的第一种方法是传递对
g_centrum
的引用,但是GLFW不会对回调的参数产生任何偏差

我的第二次尝试是在构造函数中声明和定义回调,但您不能这样做


我的第三次尝试是使
g\u centrum\uu
静态,但我必须在构造函数之外给它引用,我认为这不是一个优雅的解决方案。

在注册回调之前,使用
glfwSetWindowUserPointer()
将包装器指针与窗口相关联。调用回调时,可以使用
glfwGetWindowUserPointer()
检索它。中介绍了这些API

窗口用户指针 每个窗口都有一个用户指针,可以使用glfwSetWindowUserPointer设置,并使用glfwSetWindowUserPointer获取。这可以用于您需要的任何目的,并且在窗口的整个生命周期内不会被GLFW修改

例如,您可以在
WindowWrapper
构造函数中执行此操作:

WindowWrapper::WindowWrapper(Centrum* g_centrum){
    g_centrum_ = g_centrum;
    // Initialize window first
    ...
    // Now, associate the wrapper to the window
    glfwSetWindowUserPointer(window_, this);

    glfwSetKeyCallback(window_, key_callback); // Problems

    // Window loop and OpenGL stuff
}
然后,在回调中:

void WindowWrapper::key_callback(
    GLFWwindow* window, int key, int scancode, int action, int mods
    ){

    void *data = glfwGetWindowUserPointer(window);  
    WindowWrapper *w = static_cast<WindowWrapper *>(data);

    w->g_centrum_->input_eventmanager_->key_eventmanager_->
        TriggerKeyEvent(key, action, mods);
}
void WindowWrapper::key\u回调(
GLFWwindow*窗口,int键,int扫描码,int操作,int mods
){
void*data=glfwGetWindowUserPointer(窗口);
WindowWrapper*w=静态_转换(数据);
w->g\u centrum->input\u eventmanager->key\u eventmanager->
TriggerKeyEvent(按键、动作、mods);
}

您可以有一个静态映射,将每个
GLFWindow*
映射到其相应的
窗口包装器

private:
    static std::map<GLFWindow*, WindowWrapper*> m_instanceMap;
    ...
在析构函数中,将其删除:

m_instanceMap.erase(window_);
现在,在(静态)回调方法中,您可以查找类实例,并调用每个实例方法:

void WindowWrapper::key_callback(
    GLFWwindow* window, int key, int scancode, int action, int mods)
{
    WindowWrapper* pThis = m_instanceMap[window];
    pThis->keyHandler(key, scancode, action, mods);
}

其中,
keyHandler()
是一个常规实例方法。

与其让
WindowWrapper
持有
GLFWwindow*
指针,不如从
GLFWwindow
派生它。然后,
key\u callback
可以将其
window
参数向下转换为
WindowWrapper*
并访问其成员。GLFW是一个框架,
GLFWwindow
是不透明的。@jxh它是某种结构。你不需要知道它里面有什么才能从中得到。如果感觉不正确,另一种方法是定义一个结构,该结构将
GLFWwindow
作为它的第一个成员(然后是额外的成员)。同样,您可以将
GLFWwindow*
指针强制转换为该结构指针,并访问额外的成员。@IgorTandetnik:您不能从不透明对象继承。您所说的“不透明对象”是什么?我的C++标准的副本没有提到这样的事情。如果框架不提供支持关联用户数据(+ 1)的话,映射是唯一的方法。是的,在没有真正支持的前提下,这是一个通用的解决方案。因为在这个特定的案例中它显然是受支持的,所以使用它当然更好。我有点迷路了,API页面并没有给我太多的东西去继续(我对这一点了解甚少)。你能举个抽象的例子吗?
void WindowWrapper::key_callback(
    GLFWwindow* window, int key, int scancode, int action, int mods)
{
    WindowWrapper* pThis = m_instanceMap[window];
    pThis->keyHandler(key, scancode, action, mods);
}