JNA:将struct指针设置为NULL

时间:2016-03-22 09:59:05

标签: java pointers null jna

我开始使用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是我的域名。

有没有人有类似的问题?也许我只是没有看到树木的木头......

提前致谢。

1 个答案:

答案 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()