我正在使用GLFW3(窗口库)制作应用程序,我的操作系统是Windows 8.1。
我的错误:我在主线程中创建了一个指针,当窗口的线程尝试使用它时,它会获得access violation。
在我的应用程序中,我试图创建一个输入处理程序类,它从窗口接收事件并将它们发送到订阅该事件的所有对象。
为此,我有所有想要监听的对象继承InputListener
:
class InputListener{
public:
virtual void onKeyDown(int key) = 0;
};
要订阅一个事件,一个对象必须使用一个伪全局(传递给构造类的引用)包装变量,它包含我的InputHandler
:
// My global wrapper
#include "InputHandler.h"
class Centrum{
public:
InputHandler inputHandler;
public:
Centrum(){}
};
InputHandler
class InputHandler{
private:
unsigned numEvents;
InputListener* key_down; // Only trying to test on one subscriber for now.
public:
InputHandler();
void registerKeyDown(InputListener* listener, int key);
void key_event(int key, int action); // Is indirectly called by glfw window (same thread though)
};
// Implementation
InputHandler::InputHandler(){
numEvents = 0;
}
void InputHandler::registerKeyDown(InputListener* listener, int key){
// This is called from my main thread
key_down = listener;
key_down->onKeyDown(key); // Properly calls function on my Camera class which inherits InputListener
numEvents++;
printf("yes %u\n", numEvents);
}
void InputHandler::key_event(int key, int action){
// This is called by the window's thread (glfw automatically makes this thread)
printf("failure %u\n", numEvents); // Properly prints out numEvents
key_down->onKeyDown(key); // Runtime error here, access violation
}
订阅输入的示例:
Camera::Camera(Centrum& g_centrum){
this->g_centrum = g_centrum;
[...]
g_centrum.inputHandler.registerKeyDown(this, GLFW_KEY_W);
}
答案 0 :(得分:1)
指向的变量在可以使用之前就已经死了。因此,当线程尝试使用它时,它会引发运行时错误。
答案 1 :(得分:0)
在这一行中你正在复制Centrum:
this->g_centrum = g_centrum;
然后注册该副本(首次调用onKeyDown
,这自然起作用)。但是你还没有注册到原来的Centrum,所以它没有key_down
来调用,所以当它试图这样做时,不检查指针是否有效,它就会失败。
我将g_centrum
作为指针,并且可能使用指针而不是始终引用Centrum。
答案 2 :(得分:0)
线程具有单独的堆栈,因此只有堆分配的对象才能被多个线程访问。 此外,您应该通过互斥锁防止对这些对象(或至少是并发数据)的并发访问。
如果在Windows线程中实现了Camera,您将创建一个centrum副本。
Camera::Camera(Centrum& g_centrum){
this->g_centrum = g_centrum;
[...]
g_centrum.inputHandler.registerKeyDown(this, GLFW_KEY_W);
}
您应该像Centrum
那样实现Centrum *mycentrum = new Centrum()
,并将其作为指向相机的指针传递。