我开始使用JNA与计算机的RS485接口上的设备进行通信。令我惊讶的是,我很快就取得了良好的效果。但现在我被一个简单的问题所困扰。我使用的库接受指向struct指针的指针。实际签名是
func(Struct1 **, Struct2 **, Struct3 *, Struct4 *, long)
现在指示库期望最后一个指针为NULL指针的第一个参数的大小。这是失败的。以下代码是我到目前为止所尝试的:
Struct1.ByReference[] s = (Struct1.ByReference[]) new Struct1.ByReference().toArray(size);
int pos = 0;
// ...
// for loop to set the s[pos] struture values
for(pos = 0; pos < size - 1; pos++)
// ...
// Now set the last array element to a null pointer to indicate end-of-list
s[pos].getPointer().setPointer(0, null);// Following does not work: results in zero memoried structure
s[pos] = null; // Following does not work wither: NullPointerException at com.sun.jna.Structure.autoWrite
编辑1
s[pos] = new Struct1.ByReference(Pointer.NULL); // results in zero memoried structure as well
编辑2
根据technomage的问题。如果我要编写C代码,它可能看起来像这样:
Struct1 **s = malloc(n * sizeof(Struct1*));
for(int i=0; i<n; i++)
{
if(i == n -1)
{
s[i] = NULL;
}
else
{
s[i] = malloc(sizeof(Struct1));
s[i].bla = value;
....
}
}
但要注意:我对C / C ++不是很熟练。我认为Java是我的域名。
有没有人有类似的问题?也许我只是没有看到树木的木头......
提前致谢。
答案 0 :(得分:0)
JNA中的结构是指针,所以你真正需要的是指向(指向a)结构的指针,在你的情况下是一个PointerByReference
,它们是一个数组。
鉴于上面的代码示例,您将创建一个Structures数组,比n:
少一个Struct1[] struct1Array = new Struct1[n-1];
这只为数组分配Java内存。
接下来,您将实例化并将您对本机内存所做的更改写入:
for (int i = 0; i < n-1; i++) {
struct1Array[i] = new Struct1();
struct1Array[i].bla = value;
struct1Array[i].write();
}
new Struct1()
为这些结构分配本机端内存。也可以使用Structure.toArray()
方法来执行此操作;我故意这样做一些手动和低级别,试图弄清楚发生了什么。
然后,您将创建一个相应的PointerByReference
数组来保存指向这些结构的指针。你将为null添加一个额外的元素:
PointerByReference[] pbrArray = new PointerByReference[n];
同样,这只是java端分配。然后用指向结构的指针填充它,从Structure.getPointer()
方法获得:
for (int i = 0; i < n-1; i++) {
pbrArray[i] = new PointerByReference(struct1Array[i].getPointer());
}
pbrArray[n - 1] = new PointerByReference(Pointer.NULL);
此处new PointerByReference()
为指针本身分配本机端内存,指向您之前分配的本机端结构。
从我如何理解您的初始问题,您将把这个PointerByReference
数组传递给您的函数,这可能会更新您的结构。
由于您以这种方式创建了两个数组,因此可以通过数组索引跟踪它们的对应关系。您可能必须遍历结构数组并将read()
本机内存迭代到Java端结构中,以便使用它进行进一步处理。通常,当您直接使用Structures传递给方法时,它们会自动写入和自动注册,但是当使用PointerByReference
间接引用结构时,JNA并不友好。
作为通过相应索引跟踪两个数组的替代方法,您可以“忘记”初始结构分配并稍后使用阵列上的PointerByReference.getValue()
方法恢复它以恢复指向结构内存的指针,然后在其构造函数中使用该指针实例化一个新结构(例如new Struct1(pbr.getValue())
使用该指针调用super()
。