JNA和Structure数组作为参数

时间:2015-06-24 09:07:12

标签: java arrays sockets jna

我使用JNA访问SocketCAN。但是我遇到了setsockopt函数的问题。

功能声明:

java.specification.version

SocketCAN使用以下结构:

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

可以设置一个过滤器,其中一个can_filter结构作为参数,或者多个具有can_filter结构数组的过滤器。

来自SocketCAN的示例:

struct can_filter {
            canid_t can_id;
            canid_t can_mask;
    };

如果我将一个结构的函数定义为JNA中的参数,那么它运行没有问题:

    struct can_filter rfilter[2];

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id   = 0x200;
    rfilter[1].can_mask = 0x700;

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

如果我为结构数组定义函数,那么我在init处得到一个错误:

private static native int setsockopt(int sockfd, int level, int option_name, CanFilterStruct filter, int len);

发生错误:

private static native int setsockopt(int sockfd, int level, int option_name, CanFilterStruct[] filters, int len);

这里是JNA中结构的定义:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at de.comp.test.App.main(App.java:42)
Caused by: java.lang.IllegalArgumentException: class [Lde.comp.jsocketcan.CanFilterStruct; is not a supported argument type (in method setsockopt in class de.comp.jsocketcan.SocketCan)
    at com.sun.jna.Native.register(Native.java:1463)
    at com.sun.jna.Native.register(Native.java:1396)
    at com.sun.jna.Native.register(Native.java:1156)
    at de.comp.jsocketcan.SocketCan.<clinit>(SocketCan.java:70)

有人可以帮助我吗?

祝你好运

1 个答案:

答案 0 :(得分:0)

使用Structure.toArray()获取连续分配的结构块,然后传入第一个元素。

修改

您的参数类型仍为CanFilterStruct

显式:

CanFilterStruct s = new CanFilterStruct();
CanFilterStruct[] array = (CanFilterStruct[])s.toArray(length);

lib.setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, array[0], array.length * array[0].size());