構造体へのポインタを取る関数を持つ C DLL で関数を呼び出そうとしています。この構造体 ( Data
) は次のように定義されます。
struct BD
{
char* Data;
int Length;
};
struct EE
{
char* Key;
BD* Value;
};
struct Data
{
char* Name;
BD* Picture;
// A NULL-terminated array of pointers to EE structures.
EE** Elements;
};
Java では、次のようないくつかのクラスを定義しました。
public static class BD extends Structure implements Structure.ByReference {
public byte[] Data;
public int Length;
}
public static class EE extends Structure implements Structure.ByReference {
public String Key;
public BD Value;
}
public static class Data extends Structure {
public String Name;
public BD Picture;
public PointerByReference Elements;
}
Data
しかし、オブジェクトを正しく設定する方法が正確にはわかりません。Name
フィールドとフィールドを理解できると思いますPicture
が、フィールドを何に設定すればよいElements
ですか? オブジェクトの Java 配列を作成できますEE
が、そこから PointerByReference を取得するにはどうすればよいですか? Elements
として宣言する必要があるかもしれませんがPointer[]
、配列の各要素にgetPointer()
for eachEE
オブジェクトを入力するだけでよいでしょうか? しかし、それは正しくないように思えますか?
編集:私がやろうとしていることをよりよく理解するために:
Data data = new Data();
// Fill in Name and Picture fields.
EE[] elements = new Elements[10];
// Fill in the elements array.
// Now how do I set the Elements field on the data object from the elements array?
data.Elements = ???
Edit2:テクノメージの助けを借りて解決した方法は次のとおりです。
Data
構造を次のように変更しました。
public static class Data extends Structure {
public String Name;
public BD Picture;
public Pointer Elements;
}
そして、私のBD
構造は次のようになります。
public static class BD extends Structure implements Structure.ByReference {
public Pointer Data;
public int Length;
}
Javabyte[]
を JNAPointer
に変換するには、以下を使用する必要がありましたByteBuffer
。
ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
buf.put(bytes);
bd.Data = Natvie.getDirectBufferPointer(buf);
ByteBuffer
残念ながら、JNA は構造内の s を好みません。
要素ポインターを取得するには、Pointer
各EE
オブジェクトへの s の配列を作成する必要がありました (実装については、technomage の回答を参照してくださいPointerArray
)。
EE e = new EE();
// Populate e object.
// ...
// Important: ensure that the contents of the objects are written out to native memory since JNA can't do this automatically
e.write();
ptrs.add(e);
// Once each object is setup we can simply take the array of pointers and use the PointerArray
data.Elements = new PointerArray(ptrs.toArray(new Pointer[0]));
ByteBuffer
orを構造定義で直接使用できなかっPointerArray
たので、 に依存する必要がありましたPointer
。