我的节目中断了并且说了这个
Unhandled exception at 0x00f85069 in Monopoly.exe: 0xC0000005: Access violation writing location 0x0000000c.
我做了一个win32包装器。我有两个WndProc一个是静态而另一个不是。静态WndProc调用非静态WndProc。当我尝试获取消息时它工作正常,但是当我尝试为某些东西设置值时会抛出异常 这是我的两个WndProc的代码(第一个是静态的)
LRESULT CALLBACK Window::StaticWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
if ( msg == WM_CREATE )
{
SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG)((CREATESTRUCT *)lParam)->lpCreateParams );
}
Window *targetApp = (Window*)GetWindowLongPtr( hWnd, GWLP_USERDATA );
return targetApp->WndProc( hWnd, msg, wParam, lParam );
}
LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
z=-14; //IT THROW EXCEPTION
break;
case WM_RBUTTONDOWN:
z-=1;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
先谢谢
修改
VARABILES
int z;
答案 0 :(得分:1)
嗯,访问冲突(0xC0000005
)意味着你访问了你不应该拥有的内存。在这种情况下,它表示您正在尝试写入0x0000000c
。既然你(你的调试器?)说z
的赋值导致它,我们可以看到那个符号的定义吗?此外,它真的是z = -14
还是z -= 14
?
编辑:我认为您需要使用指向((CREATESTRUCT *)lParam)->lpCreateParams
实例的有效指针替换class Window
。
编辑#2:会发生什么:在WM_CREATE
上,您将GWLP_USERDATA
设置为恰好等于NULL
的值。随后,您通过在该指针上调用非静态成员函数来读取该值并将其视为指向Window
的有效指针。类成员函数由编译器实现实现
LRESULT CALLBACK <mangled_name ("Window::WndProc")> (Window * const this, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
// ...
}
这就是你可以在NULL
指针上实际调用成员函数的原因。但是,一旦访问成员变量,例如z
,就会中断。编译器插入的代码类似于*((int*) (this + 0xc)) = -14
,(BTW意味着z
位于Window
实例中的0xc字节),自this == NULL
以来,它已经破坏。
答案 1 :(得分:1)
您正在调用WndProc
的对象似乎不存在(null?),并且在尝试在z -= 14
中写入内存时遇到访问冲突,this->z -= 14
}(this
是无效指针)。这是我的猜测。
此外,访问冲突在C ++术语中也不例外。 :)
答案 2 :(得分:1)
你是如何创建窗口的?您是否通过Window
参数向CreateWindow()
或CreateWindowEx()
函数传递了lpParam
实例的有效指针?例如,如果您的窗口包装器具有Create()
函数或类似的东西:
void Window::Create()
{
/* ... */
// Pass a pointer to ourselves to CreateWindow() via the lpParam parameter.
// CreateWindow() then passes that pointer to your window procedure
// (StaticWndProc) via WM_CREATE and WM_NCCREATE in the lpCreateParams member
// of CREATESTRUCT. This way the window procedure will know which instance to
// call WndProc() on.
CreateWindow(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
hWndParent, hMenu, hInstance, (LPVOID)this);
/* ... */
}