C++ 输入奇怪的行为

C++ 输入奇怪的行为,c++,winapi,raw-input,C++,Winapi,Raw Input,我的输入有点奇怪。以下代码有效: case WM_INPUT: { UINT rawInputSize; GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, nullptr, &rawInputSize, sizeof(RAWINPUTHEADER)); LPBYTE inputBuffer = new BYTE[rawInputSize]; GetRawInputData((HRAWINPUT)(

我的输入有点奇怪。以下代码有效:

case WM_INPUT:
{
     UINT rawInputSize;

     GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, nullptr, &rawInputSize, sizeof(RAWINPUTHEADER));

     LPBYTE inputBuffer = new BYTE[rawInputSize];

     GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));

     RAWINPUT* inp = (RAWINPUT*)inputBuffer;   // valid
}
但以下措施不起作用:

case WM_INPUT:
{
     UINT rawInputSize;
     BYTE inputBuffer[40];

     GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));        // returns error code

     RAWINPUT* inp = (RAWINPUT*)inputBuffer;
}
也不是:

两者都在
GetRawInputData()
处失败,返回一般错误代码(无详细信息)

我首先发布的工作解决方案不是一个选项,我不能在每次击键或鼠标操作时进行堆分配,我必须使用堆栈

为什么最后两个失败?

的第四个参数,
pcbSize
,有两个功能。输入时,它指定可用缓冲区的长度。退出时,它包含实际使用的数据的长度。这是Windows API中相当常见的概念

在第一种情况下,即第一次调用中,不使用输入值,在退出时只存储所需的长度。第二个调用有效,因为所需的长度仍然存在

但在第二个和第三个示例中,未初始化变量,因此它包含堆栈中的随机垃圾。显然是接近
0
,这使得函数失败。但那只是猜测,当然有很多方法无法做到这一点,崩溃等等

应按如下方式初始化变量:

RAWINPUT inputBuffer;
UINT rawInputSize = sizeof(inputBuffer);
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));

作为旁注,在使用第二个示例中的
BYTE[]
数组时要小心——一些Alexander Belyakov在API文档页面上发表了以下有用的评论:

在Win64上,GetRawInputData将返回-1,错误为\u NOACCESS,除非pData缓冲区按8字节对齐


它会返回什么错误代码?没有任何说明-MSDN:“如果有错误,返回值是(UINT)-1。”对于未来,
GetLastError()
通常在这些情况下会有真正的错误代码。文档中没有明确说明,但我相信它仍然适用于这种情况。
RAWINPUT inputBuffer;
UINT rawInputSize = sizeof(inputBuffer);
GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &inputBuffer, &rawInputSize, sizeof(RAWINPUTHEADER));