2012-04-11 8 views
0

Ich habe eine C-Bibliothek, die eine Struktur verwendet, die ein Array einer anderen Struktur enthält. Ich habe einige Schwierigkeiten, den richtigen Weg zu bestimmen, um von Java über JNA darauf zuzugreifen.Verwenden von JNA, um auf eine Struktur zuzugreifen, die ein Array von Strukturen enthält

Der C-Code ist wie folgt:

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; 
} 

ich in der Lage bin mit dieser aus einer C-Anwendung mit dem folgende Beispiel zu arbeiten:

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

Ich habe versucht, diese von Java zugreifen (über JNA) mit dem folgenden Java-Code:

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

Allerdings führt die obige Java zu einem Core-Dump.

ich versuchte, die ItemList Definition ändert (in Java) ein Array von Item.ByValue zu verwenden:

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; 
} 

und verändert dann die Verwendung (in Java) auf:

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

aber mit das gleiche Ergebnis.

Ich habe versucht, auch die C-Funktion Unterschrift Wechsel zu

int addItemList(ItemList* list); 

und die C-Implementierung entsprechend angepasst. Dann habe ich den Java-Code geändert, um eine CLibrary.ItemList.ByReference an addItemList zu übergeben - aber mit den gleichen Ergebnissen.

Was fehlt mir? Was ist der geeignete Weg, um eine Struktur mit einem Array von Strukturen von Java zu C mit JNA übergeben?

+0

Ihre Struktur enthält kein Array von Struktur, sondern einen Zeiger auf dieses Array. – technomage

Antwort

1

konnte mich mit dem Original-C-Code arbeiten, indem Sie den folgenden Java-Code verwenden:

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

Wie ich oben sehen Sie ein Problem haben.

Oben Code, wurden unter Verwendung von Ihnen Item.ByValue auf Artikel *

Aber es sollte Item.ByReference sein.