This question already has answers here:
Direct2D : Unhandled Exception In WM_RESIZE switch case
(2个答案)
4个月前关闭。
按照Direct2D的官方教程(https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-quickstart)使用Visual Studio 2019创建示例项目。在x86中运行代码时,将平台更改为x64时一切正常,我收到一条错误消息:'抛出了异常:已读访问冲突。”在SampleD2D.cpp中。 (在下面的代码中注释了该行)
错误是:
特别是
这可能适用于32位应用程序,但不适用于64位。
因此,将指针转换为
搜寻这个方向,例如PtrToUlong Q/A on gamedev.net(旧的答案):
msdn,请尝试避免使用这些,因为您将指针强制转换为无符号的long。这可能在32位可执行文件上正常运行,但是如果您以64位编译,则可能会遇到问题。
这支持了我的怀疑。
根据MS文档。 SetWindowLongPtrW function,签名为:
因此,这应该解决它:
请注意MS文档。关于
LONG_PTR
带符号的long类型用于指针精度。在将指针强制转换为long类型以执行指针算术时使用。
在BaseTsd.h中声明此类型,如下所示:
C ++
顺便说一句。我也不太明白
根据文件。 GetWindowLongPtrW function,该函数返回
(2个答案)
4个月前关闭。
按照Direct2D的官方教程(https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-quickstart)使用Visual Studio 2019创建示例项目。在x86中运行代码时,将平台更改为x64时一切正常,我收到一条错误消息:'抛出了异常:已读访问冲突。”在SampleD2D.cpp中。 (在下面的代码中注释了该行)
错误是:
Exception thrown: read access violation.
this was 0xBB18F6E8.
LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
DemoApp* pDemoApp = (DemoApp*)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDemoApp)
);
result = 1;
}
else
{
DemoApp* pDemoApp = reinterpret_cast<DemoApp*>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pDemoApp->OnResize(width, height); // throw the error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pDemoApp->OnRender();
ValidateRect(hwnd, NULL);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}
最佳答案
不幸的是,我不是WinAPI专家,但是出于好奇,我用Google搜索了一下。现在,我非常确定OP的问题:
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDemoApp)
);
特别是
PtrToUlong(pDemoApp)
。这可能适用于32位应用程序,但不适用于64位。
long
是MS VC ++ 32位-用于x86和x64平台。因此,将指针转换为
long
或unsigned long
有助于在x64上将其错误(只要高32位不为0,这可能很难预测)。搜寻这个方向,例如PtrToUlong Q/A on gamedev.net(旧的答案):
msdn,请尝试避免使用这些,因为您将指针强制转换为无符号的long。这可能在32位可执行文件上正常运行,但是如果您以64位编译,则可能会遇到问题。
这支持了我的怀疑。
根据MS文档。 SetWindowLongPtrW function,签名为:
LONG_PTR SetWindowLongPtrW(
HWND hWnd,
int nIndex,
LONG_PTR dwNewLong
);
因此,这应该解决它:
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
reinterpret_cast<LONG_PTR>(pDemoApp)
);
请注意MS文档。关于
LONG_PTR
:LONG_PTR
带符号的long类型用于指针精度。在将指针强制转换为long类型以执行指针算术时使用。
在BaseTsd.h中声明此类型,如下所示:
C ++
#if defined(_WIN64)
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
#endif
顺便说一句。我也不太明白
DemoApp* pDemoApp = reinterpret_cast<DemoApp*>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
根据文件。 GetWindowLongPtrW function,该函数返回
LONG_PTR
。那么,为什么static_cast<LONG_PTR>
?如果绝对必要,则类型转换应始终是最后的选择。 (尽管,我承认如果没有,WinAPI可能无法使用。)关于c++ - 遵循官方的direct2d示例,但出现访问冲突错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57522391/
10-10 16:18