2012-04-11 51 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; 
} 

Iは、以下の例で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); 

Iは、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ではコアダンプが発生します。

IはItem.ByValueのアレイを使用する(Javaで)ITEMLIST定義を変更しようとした:

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

しかしと同じ結果。

Iはまた

int addItemList(ItemList* list); 

にC関数シグネチャを変更し、それに応じてCインプリメンテーションを調整しようとしています。次に、Javaのコードを変更して、CLibrary.ItemList.ByReferenceをaddItemListに渡しましたが、同じ結果が得られました。

私には何が欠けていますか? JNAを使用して、Javaの構造体の配列を含む構造体をCに渡す適切な方法は何ですか?

+0

構造体には構造体の配列は含まれていませんが、その配列へのポインタが含まれています。 – technomage

答えて

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する必要があります。

関連する問題