如何在JNA中填充结构数组? [英] How to fill an array of structures in JNA?

查看:129
本文介绍了如何在JNA中填充结构数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在JNA中使用以下Windows API:

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是RAWINPUTDEVICELIST结构的大小,以字节为单位.如何在JNA中知道它?我偶然发现16是正确的值.

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.

结构如下:

typedef struct tagRAWINPUTDEVICELIST {
  HANDLE hDevice;
  DWORD  dwType;
} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;

pRawInputDeviceList是RAWINPUTDEVICELIST结构的数组,因此在JNA中,我声明以下签名:

pRawInputDeviceList is An array of RAWINPUTDEVICELIST structures so in JNA I'm declaring the following signature :

UINT GetRawInputDeviceList(PointerByReference pRawInputDeviceList, IntByReference puiNumDevices, UINT cbSize);

这是我在JNA中的结构:

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" });
    }

}

当我获取PointerByReference值以获取指针时,它为null,这有什么问题呢?设备数量正确,但无法正确获取RawInputDeviceList数组.

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.

这是完整的测试代码:

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" });
            }

        }
    }

}

推荐答案

  1. 使用 Structure.toArray()创建一个连续分配的结构数组.
  2. 将该数组的第一个元素传递给您的本机函数.在这种情况下, struct * 等效于 struct [] (本机类型),因此请使用 RawInputDeviceList 作为参数类型,而不是PointerByReference .我不确定为什么他们将单个结构称为列表",但这就是您的窗口.
  3. puiNumDevices 中传递数组的大小,大概是本机函数将使用实际填写的计数进行更新.
  4. 本机函数将填充内存,并且JNA将在函数返回时将本机内存同步到Java Structure .
  5. 可以通过调用 Structure.size()获得
  6. cbSize .
  1. Create an array of continguously-allocated structures using Structure.toArray().
  2. Pass the first element of that array to your native function. In this case, 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.
  3. Pass the size of your array in puiNumDevices, which presumably the native function will update with the count actually filled in.
  4. The native function will fill in the memory, and JNA will sync the native memory to Java Structure on function return.
  5. cbSize may be obtained by calling Structure.size().

这篇关于如何在JNA中填充结构数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆