GLFW keycallback用户指针不携带数据

时间:2016-04-16 02:49:27

标签: c++ c++11 opengl glfw

我正在尝试将数据从我的应用程序发送到GLFW keyCallback,然后我访问并修改该数据。但是,如果没有应用程序崩溃,我可以访问或更改任何内容。我做错了什么?

//main.cpp
typedef struct
{
    string type, name;
} DebugUsrPtr;

//hot loop
{
    DebugUsrPtr myPtr;
    myPtr.type = "aaa";
    myPtr.name = "bbb";
    void *testPtr = &myPtr;

    glfwSetWindowUserPointer(myWin, testPtr);
    glfwSetKeyCallback(myWin, keyCallback0);
    glfwSetWindowUserPointer(myWin, myWin);
}

//input.cpp
void keyCallback0(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    auto *myTest = static_cast<DebugUsrPtr*>(glfwGetWindowUserPointer(window));
    cout << "name test = " << myTest->name << endl; // ""
    myTest->name = "zzzz"; //prints "zzzz" for one frame then appcrash
}

1 个答案:

答案 0 :(得分:1)

在这一行:

glfwSetWindowUserPointer(myWin, myWin);

当你设置它时,用户指针现在指向窗口结构,而不是你的结构。因此,当调用回调(稍后调用)时,它不再指向您的调试结构,而是指向Windows指针。

您需要将指针发送到您的结构,只要您认为自己需要它就可以使用它。

你有另一个错误,在调用回调之前销毁了调试结构:

{
    DebugUsrPtr myPtr;
    myPtr.type = "aaa";
    myPtr.name = "bbb";
    void *testPtr = &myPtr;

    glfwSetWindowUserPointer(myWin, testPtr);
    glfwSetKeyCallback(myWin, keyCallback0);
    glfwSetWindowUserPointer(myWin, myWin);
} // debug structure destroyed here!

因此,当稍后调用回调时,调试结构将被释放,这将导致未定义的行为!

为此,我认为您应该在事件循环的父作用域中声明您的结构。就像这样:

DebugUsrPtr myPtr;
// ...
{
    glfwSetWindowUserPointer(myWin, &myPtr);
    glfwPollEvents(); // the callback will be called here if user press keys!
}

如果你真的在做C ++,请改为声明你的结构:

struct DebugUsrPtr {
    std::string type, name;
};

如果你想为每个回调使用不同的类型或不同的指针,请将它们全部保存在更大的结构中:

struct AllPointers {
    DebugUsrPtr dbg;
    MouseUsrPtr mouse;
    // more...
};