2012-04-11 84 views
0

我有一个C库,它使用一个包含另一个结构数组的结构。我在确定通过JNA访问Java的正确方法时遇到了一些困难。使用JNA访问包含结构数组的结构

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访问这个(通过JNA)使用以下Java代码:

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

您的结构不包含结构数组,而是指向该数组的指针。 – technomage 2012-04-11 18:42:04

回答

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); 
2

当我看到在上面你已经有了一个问题。

在你的代码之上,你就 项目 *

使用Item.ByValue但应Item.ByReference