我正在尝试调用 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
字段呢?我可以创建一个 EE
对象的 Java 数组,但是如何从中获取 PointerByReference 呢?也许我需要将 Elements
声明为 Pointer[]
但我只需使用 getPointer()
填充数组的每个元素即可每个EE
对象?但这似乎不太正确?
编辑:为了更好地了解我正在尝试做什么:
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:以下是我在 technomage 的帮助下解决该问题的方法:
我将我的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;
}
要将 Java byte[]
转换为 JNA Pointer
,我必须使用 ByteBuffer
:
ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
buf.put(bytes);
bd.Data = Natvie.getDirectBufferPointer(buf);
不幸的是,JNA 不喜欢结构中的 ByteBuffer
。
为了获取我的元素指针,我需要创建一个指向每个 EE
对象的 Pointer
数组(请参阅 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
或 PointerArray
,因此我必须依赖 Pointer
。
最佳答案
将 Elements
设为 Pointer
,然后使用 Pointer.getPointerArray(0)
检索感兴趣的结构指针。
然后,您需要从每个检索到的 Pointer
初始化每个 Structure
(不要忘记调用 Structure.read()
) .
没有办法自动执行指针上的间接寻址并最终得到一个 Structure
数组,但它很简单,可以编码到 Structure
上的方法中类(例如 Data.getElements()
)。
编辑
示例指针数组实现,在写入(而不是读取)时初始化指针数组:
class PointerArray extends Memory {
private final Pointer[] original;
public PointerArray(Pointer[] arg) {
super(Pointer.SIZE * (arg.length+1));
this.original = arg;
for (int i=0;i < arg.length;i++) {
setPointer(i*Pointer.SIZE, arg[i]);
}
setPointer(Pointer.SIZE*arg.length, null);
}
}
}
在调用 native 函数之前,您还需要调用 Structure.write()
(您可以将其作为 PointerArray
的一部分执行此操作),因为 JNA 不这样做知道当您使用普通的 Pointer
而不是 Structure
时,内存需要同步。
关于java - 如何使用指向 Java 指针的指针填充结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17556456/