Reputation: 213
I am trying to use the following windows API in JNA :
UINT WINAPI GetRawInputDeviceList(
_Out_opt_ PRAWINPUTDEVICELIST pRawInputDeviceList,
_Inout_ PUINT puiNumDevices,
_In_ UINT cbSize
);
UINT cbSize is the size of a RAWINPUTDEVICELIST structure, in bytes. How to know it in JNA? I had accidentally found that 16 is a correct value.
The structure is the following:
typedef struct tagRAWINPUTDEVICELIST {
HANDLE hDevice;
DWORD dwType;
} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
pRawInputDeviceList is An array of RAWINPUTDEVICELIST structures so in JNA I'm declaring the following signature :
UINT GetRawInputDeviceList(PointerByReference pRawInputDeviceList, IntByReference puiNumDevices, UINT cbSize);
And here is my structurre in JNA :
public static class RawInputDeviceList extends Structure {
public HANDLE hDevice;
public DWORD dwType;
public RawInputDeviceList() {
// required for toArray()
}
public RawInputDeviceList(Pointer pointer) {
super(pointer);
read();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "hDevice", "dwType" });
}
}
When i'm getting the PointerByReference value to get the pointer it is null, what is wrong with that? The number of devices is correct bu i can't get the RawInputDeviceList array correctly.
Here is the full test code:
public class TestRawInput {
public static void main(String[] args) {
PointerByReference lRawInputDevicesReference = new PointerByReference();
IntByReference lNumDevices = new IntByReference();
UINT lRes = WindowsRawInput.INSTANCE.GetRawInputDeviceList(lRawInputDevicesReference, lNumDevices, new UINT(16));
Pointer lRawInputDevicePointer = lRawInputDevicesReference.getValue();
WindowsRawInput.RawInputDeviceList lRawInputDevice = new WindowsRawInput.RawInputDeviceList(lRawInputDevicePointer);
WindowsRawInput.RawInputDeviceList[] lDevices = (WindowsRawInput.RawInputDeviceList[]) lRawInputDevice.toArray(lNumDevices.getValue());
System.out.println("devices deteced=" + lNumDevices.getValue());
for (int i=0;i<lDevices.length;i++) {
System.out.println("device type: " + lDevices[i].dwType);
}
}
public interface WindowsRawInput extends StdCallLibrary {
WindowsRawInput INSTANCE = (WindowsRawInput) Native.loadLibrary("user32", WindowsRawInput.class, W32APIOptions.DEFAULT_OPTIONS);
UINT GetRawInputDeviceList(PointerByReference pRawInputDeviceList,
IntByReference puiNumDevices, UINT cbSize);
public static class RawInputDeviceList extends Structure {
public HANDLE hDevice;
public DWORD dwType;
public RawInputDeviceList() {
// required for toArray()
}
public RawInputDeviceList(Pointer pointer) {
super(pointer);
read();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "hDevice", "dwType" });
}
}
}
}
Upvotes: 2
Views: 2051
Reputation: 213
Here is the final code after technomage's answer :
using JNA and native library :
IntByReference lNumDevices = new IntByReference();
WindowsRawInput.RAWINPUTDEVICELIST lRawInputDevice = new WindowsRawInput.RAWINPUTDEVICELIST();
int lRawInputSize = lRawInputDevice.size();
// getting the size of devices to get and setting the structure size
WindowsRawInput.INSTANCE.GetRawInputDeviceList(null, lNumDevices, lRawInputSize);
// creating the device list
WindowsRawInput.RAWINPUTDEVICELIST[] lDevices = (WindowsRawInput.RAWINPUTDEVICELIST[]) lRawInputDevice.toArray(lNumDevices.getValue());
WindowsRawInput.INSTANCE.GetRawInputDeviceList(lDevices[0], lNumDevices, lRawInputSize);
Here is the JNA interface and structure :
public interface WindowsRawInput extends StdCallLibrary {
WindowsRawInput INSTANCE = (WindowsRawInput) Native.loadLibrary("user32", WindowsRawInput.class, W32APIOptions.DEFAULT_OPTIONS);
UINT GetRawInputDeviceList(RAWINPUTDEVICELIST pRawInputDeviceList, IntByReference puiNumDevices, int cbSize);
public static class RAWINPUTDEVICELIST extends Structure {
public HANDLE hDevice;
public DWORD dwType;
public RAWINPUTDEVICELIST() { }
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "hDevice", "dwType" });
}
}
}
Upvotes: 2
Reputation: 10069
Structure.toArray()
.struct*
is equivalent to struct[]
(native types), so use RawInputDeviceList
as the argument type instead of PointerByReference
. I'm not sure why they call the individual structure a "list", but that's windows for you.puiNumDevices
, which presumably the native function will update with the count actually filled in.Structure
on function return.cbSize
may be obtained by calling Structure.size()
.Upvotes: 5