我正在尝试将数据从我的应用程序发送到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
}
答案 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...
};