Arrays 使用JNA访问包含结构数组的结构

Arrays 使用JNA访问包含结构数组的结构,arrays,struct,jna,Arrays,Struct,Jna,我有一个C库,它使用一个包含另一个结构数组的结构。我很难确定通过JNA从Java访问它的正确方法 C代码如下: typedef struct Item { int x; } Item; typedef struct ItemList { int itemCount; Item* items; // an array of Item } ItemList; int addItemList(ItemList list) { int result = 0; i

我有一个C库,它使用一个包含另一个结构数组的结构。我很难确定通过JNA从Java访问它的正确方法

C代码如下:

typedef struct Item {
    int x;
} Item;
typedef struct ItemList {
    int itemCount;
    Item* items; // an array of Item
} ItemList;

int addItemList(ItemList list)
{
    int result = 0;
    int i = 0;

    for (i=0; i<list.itemCount; i++)
    {
        result += (list.items)[i].x;
    }
    return result;
}
我已尝试使用以下Java代码从Java(通过JNA)访问此文件:

public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByValue extends Item implements Structure.ByValue {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public static class ByReference extends ItemList implements Structure.ByReference {}
        public int itemCount;
        public Item[] items;
    }
    int addItemList(ItemList.ByValue items);
}

...

CLibrary.Item[] items = (CLibrary.Item[])new CLibrary.Item().toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = items;
list.itemCount = 3;
int y = clib.addItemList(list);
System.out.println(y);
public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByReference extends Item implements Structure.ByReference {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public int itemCount;
        public Item.ByReference items;
    }
    int addItemList(ItemList.ByValue items);
}

…

CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = new CLibrary.Item.ByReference();
list.itemCount = 3;
CLibrary.Item[] items = (CLibrary.Item[])list.items.toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
int y = clib.addItemList(list);
System.out.println(y);
但是,上面的Java会导致核心转储

我尝试更改ItemList定义(在Java中)以使用Item.ByValue数组:

public static class ItemList extends Structure {
    public static class ByValue extends ItemList implements Structure.ByValue {}
    public static class ByReference extends ItemList implements Structure.ByReference {}
    public int itemCount;
    public Item.ByValue[] items;
}
然后将用法(在Java中)更改为:

但结果是一样的

我还尝试将C函数签名更改为

int addItemList(ItemList* list);
并相应地调整了C的实现。然后我修改了Java代码,将CLibrary.ItemList.ByReference传递给addItemList,但结果相同


我错过了什么?使用JNA将包含结构数组的结构从Java传递到C的适当方式是什么?

我可以使用以下Java代码处理原始C代码:

public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByValue extends Item implements Structure.ByValue {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public static class ByReference extends ItemList implements Structure.ByReference {}
        public int itemCount;
        public Item[] items;
    }
    int addItemList(ItemList.ByValue items);
}

...

CLibrary.Item[] items = (CLibrary.Item[])new CLibrary.Item().toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = items;
list.itemCount = 3;
int y = clib.addItemList(list);
System.out.println(y);
public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByReference extends Item implements Structure.ByReference {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public int itemCount;
        public Item.ByReference items;
    }
    int addItemList(ItemList.ByValue items);
}

…

CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = new CLibrary.Item.ByReference();
list.itemCount = 3;
CLibrary.Item[] items = (CLibrary.Item[])list.items.toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
int y = clib.addItemList(list);
System.out.println(y);

通过使用以下Java代码,我能够使用原始C代码:

public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByValue extends Item implements Structure.ByValue {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public static class ByReference extends ItemList implements Structure.ByReference {}
        public int itemCount;
        public Item[] items;
    }
    int addItemList(ItemList.ByValue items);
}

...

CLibrary.Item[] items = (CLibrary.Item[])new CLibrary.Item().toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = items;
list.itemCount = 3;
int y = clib.addItemList(list);
System.out.println(y);
public interface CLibrary extends Library {
    public static class Item extends Structure {
        public static class ByReference extends Item implements Structure.ByReference {}
        public int x;
    }
    public static class ItemList extends Structure {
        public static class ByValue extends ItemList implements Structure.ByValue {}
        public int itemCount;
        public Item.ByReference items;
    }
    int addItemList(ItemList.ByValue items);
}

…

CLibrary.ItemList.ByValue list = new CLibrary.ItemList.ByValue();
list.items = new CLibrary.Item.ByReference();
list.itemCount = 3;
CLibrary.Item[] items = (CLibrary.Item[])list.items.toArray(3);
items[0].x = 1;
items[1].x = 2;
items[2].x = 3;
int y = clib.addItemList(list);
System.out.println(y);

正如我在上面看到的,你有个问题

除了代码之外,您还使用了上的
Item.ByValue
项目*


但它应该是
项。通过参考

正如我在顶部看到的,您遇到了一个问题

除了代码之外,您还使用了上的
Item.ByValue
项目*


但是它应该是
项。通过引用

您的结构不包含结构数组,而是指向该数组的指针。您的结构不包含结构数组,而是指向该数组的指针。