我有一个C库,它使用包含另一个struct数组的struct。我在确定通过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;
}
我可以使用以下示例从C应用程序中使用它:
ItemList list;
list.itemCount = 3;
list.items = (Item*)malloc(sizeof(Item) * 3);
list.items[0].x = 1;
list.items[1].x = 2;
list.items[2].x = 3;
int y = addItemList(list);
printf("%d\n", y);
我尝试使用以下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);
但是,上面的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中)更改为:
CLibrary.Item.ByValue[] items = (CLibrary.Item.ByValue[])new CLibrary.Item.ByValue().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);
但结果相同。
我也尝试将C函数签名更改为
int addItemList(ItemList* list);
并相应地调整了C实现。然后我更改了Java代码以将CLibrary.ItemList.ByReference传递给addItemList - 但结果相同。
我错过了什么?使用JNA将包含结构数组的结构从Java传递到C的适当方法是什么?
答案 0 :(得分:2)
正如我看到的那样,你有一个问题。
在您的代码之上,您正在使用Item.ByValue
项目 *
但它应该是Item.ByReference
。
答案 1 :(得分:1)
我可以使用以下Java代码处理原始C代码:
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);