gpt4 book ai didi

c# - C# 字节数组中的 RAWINPUT RAWHID 结构

转载 作者:太空宇宙 更新时间:2023-11-03 12:18:14 27 4
gpt4 key购买 nike

我正在尝试使用以下方法从 HID 设备读取数据:

uint dwsize = 0;
//RAWINPUT input = new RAWINPUT();
uint result = GetRawInputData(lParam, RID_INPUT, IntPtr.Zero, ref dwsize, Marshal.SizeOf(typeof(RAWINPUTHEADER)));

//_rawBuffer = new RAWINPUT(new RAWINPUTHEADER(), new RAWDATA(new RAWKEYBOARD(), new RAWHID(0,0)));
result = GetRawInputData(lParam, RID_INPUT, out _rawBuffer, ref dwsize, Marshal.SizeOf(typeof(RAWINPUTHEADER)));

此代码有效,但从 RAWHID 结构中获取字节数组存在一个问题,根据 MSDN 文档,它应该是这样的:

typedef struct tagRAWHID {
DWORD dwSizeHid;
DWORD dwCount;
BYTE bRawData[1];
} RAWHID, *PRAWHID, *LPRAWHID;

这是我的:

[StructLayout(LayoutKind.Sequential)]
internal struct RAWHID
{
public uint dwSizHid;
public uint dwCount;
public byte bRawData;
}

我试图到处寻找,但找不到有效的解决方案。我还尝试使用此代码获取 IntPtr 而不是字节数组并编码复制它:

int length = (int)(_rawBuffer.data.hid.dwCount * _rawBuffer.data.hid.dwSizHid);
byte[] bytes = new byte[length];
GCHandle pinnedPacket = GCHandle.Alloc(_rawBuffer.data.hid.bRawData, GCHandleType.Pinned);
Marshal.Copy(_rawBuffer.data.hid.bRawData, bytes, 0, length);
pinnedPacket.Free();

我固定它的原因是因为我不断收到

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

错误。

问题简短:如何使 RAWHID 结构与 C# 中的字节数组一起使用

最佳答案

我也不确定如何在结构中定义动态大小的字节数组 BYTE bRawData[1],所以我最终从原始 IntPtr 中获取它。我刚刚从 RAWHID 定义中删除了它:

[StructLayout(LayoutKind.Sequential)]
public struct RAWHID
{
public int Size;
public int Count;
}

[StructLayout(LayoutKind.Sequential)]
public struct RawInput
{
/// <summary>
/// Header for the data.
/// </summary>
public RawInputHeader Header;
public Union Data;

[StructLayout(LayoutKind.Explicit)]
public struct Union
{
[FieldOffset(0)] public RAWMOUSE Mouse;
[FieldOffset(0)] public RAWKEYBOARD Keyboard;
[FieldOffset(0)] public RAWHID HID;
}
}

下面是我实际读取数据并将其写入控制台的方式:

private static void ProcessInputMessage(Message message)
{
var headerSize = (uint) Marshal.SizeOf<RawInputHeader>();
uint rawInputSize = 0;
var result = GetRawInputData(message.LParam, RID_INPUT, IntPtr.Zero, ref rawInputSize, headerSize);
if (result != 0)
{
Console.WriteLine($"Failed to get message size: {result}");
return;
}

using var rawInputPointer = new AllocHGlobalWrapper(rawInputSize);
if (!rawInputPointer.Success)
{
return;
}

result = GetRawInputData(message.LParam, RID_INPUT, rawInputPointer.Value, ref rawInputSize, headerSize);
if (result != rawInputSize)
{
Console.WriteLine($"Failed to get raw data: {result}");
return;
}

var input = Marshal.PtrToStructure<RawInput>(rawInputPointer.Value);
var buffer = new IntPtr(rawInputPointer.Value.ToInt64() + headerSize + Marshal.SizeOf<RAWHID>());

if (input.Header.Type == RawInputType.HID)
{
for(var i = 0; i < input.Data.HID.Count; i++)
{
var data = new byte[input.Data.HID.Size];
Marshal.Copy(buffer, data, i * input.Data.HID.Size, input.Data.HID.Size);
Console.WriteLine(BitConverter.ToString(data));
}
}
}

请注意,AllocHGlobalWrapper 只是我编写的一个简单助手,用于将对 Marshal.AllocHGlobal(...) 的调用包装在调用 Marshal.FreeHGlobal( ...) 当它被处理时,所以 rawInputPointer.Value 只是返回指向分配给 RawInput 的内存的 IntPtr .

关于c# - C# 字节数组中的 RAWINPUT RAWHID 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48776221/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com