Laden...

[gelöst] Pinvoke GetRawInputData bei HID Geräten

Erstellt von WarLorD_XaN vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.559 Views
W
WarLorD_XaN Themenstarter:in
113 Beiträge seit 2006
vor 14 Jahren
[gelöst] Pinvoke GetRawInputData bei HID Geräten

Hallo Forum!

Ich verwende die Win32 RawInput Funktionalität und möchte damit die RawInput Daten von Joysticks und Gamepads auslesen.

Ich rufe die Funktion GetRawInputData auf.
Der DllImport dazu:

[DllImport(User32.DllPath)]
public static extern void GetRawInputData(IntPtr RawInput, uint Command, IntPtr Data, ref uint Size, uint HeaderSize); 

Nun will ich auf die Daten in der RAWHID Struktur in der RAWINPUT Struktur zugreifen:

uint size = (uint)Marshal.SizeOf(typeof(RawInput));
IntPtr buffer = Marshal.AllocHGlobalsize);
User32.GetRawInputData(LParam, RawInputCommandFlags.Input, buffer, ref size, User32.RawInputHeaderSize);
RawInput rawInput = (RawInput)Marshal.PtrToStructure(buffer, typeof(RawInput));

if (rawInput.Header.Type == RawInputType.HID)
{
byte[] data = new byte[rawInput.Hid.Size];
// Access Violation
Marshal.Copy(rawInput.Hid.Data, data, 0, data.Length);
}

Jedoch tritt bei Marshal.Copy eine AccessViolation auf.
Das Problem ist denke ich das dynamische Array in der RAWHID Struktur, ich weiss nicht wie ich sonst auf die Arrayelemente zugreifen soll.

Hier die 2 Strukturen von mir:


[StructLayout(LayoutKind.Explicit)]
internal struct RawInput
{
[FieldOffset(0)]
public RawInputHeader Header;
[FieldOffset(16)]
public RawMouse Mouse;
[FieldOffset(16)]
public RawKeyboard Keyboard;
[FieldOffset(16)]
public RawHid Hid;
}

internal struct RawHid
{
public int Size;
public int Count;
public IntPtr Data;
}

Könnte mir bitte hier jemand helfen?
mfg,
XaN

N
45 Beiträge seit 2006
vor 14 Jahren

Data ist kein Zeiger sondern ein Platzhalter, die Daten stehen direkt in der Struktur.

Reicht der Hinweis?

W
WarLorD_XaN Themenstarter:in
113 Beiträge seit 2006
vor 14 Jahren

Danke für die schnelle Antwort!

Aber kannst du mir das genauer erklären?

Wie bekomme ich nun mein Byte Array aus dem IntPtr?

mfg,
XaN

N
45 Beiträge seit 2006
vor 14 Jahren
internal struct RawHid
{
public int Size;
public int Count;
//public IntPtr Data; <-- ab hier beginnen die Daten und das ist kein Zeiger
}

Die Daten schließen also direkt nach Count an.

Auslesen der Daten könnte man z.B. mittels

byte[] bData = new byte[raw.hid.Size * raw.hid.Count];
Marshal.Copy(new IntPtr(buffer.ToInt32() + Marshal.SizeOf(typeof(uint)) * 2 + Marshal.SizeOf(typeof(RAWINPUTHEADER))), bData, 0, bData.Length);

W
WarLorD_XaN Themenstarter:in
113 Beiträge seit 2006
vor 14 Jahren

Hallo neolithos,

So funktionierts 👍, super und vielen Dank für die Rasche Hilfe!

Auf das wär ich nicht gekommen!

mfg,
XaN