2012-04-11 81 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