繁体   English   中英

从Java传递到C后未初始化的JNA结构数组

[英]JNA array of structures uninitialized after being passed from Java to C

我一直在相对成功地使用JNA进行从Java到我编写的小型C库的本地函数调用。 一旦了解了结构映射,内存管理和按引用传递的技巧,就可以将结构或指针从一个传递到另一个。

我现在正尝试从Java到C传递一系列结构。 这是该结构的C代码:

typedef struct key {
  int length;
  void *data;
} key_t;

我在Java中有匹配的定义:

public class Key extends Structure {

  public int length;
  public Pointer data;

  public Key() {
    this.setFieldOrder(new String[] {"length", "data"});
  }

  public void setAsLong(long value) {
    this.length = 8;
    this.data = new Memory(this.length);
    this.data.setLong(0, value);
  }

  public long longValue() {
    return this.data != null ? this.data.getLong(0) : Long.MIN_VALUE;
  }
};

如果我了解文档和在线阅读的内容,则需要通过在Java方面执行以下操作来将数组创建为连续的内存部分:

Key[] keys = new Key().toArray(2);
for (int i=0; i<2; i++) {
  k.setAsLong(42+i);
}

到现在为止还挺好。 如果我使用Structure.toString()转储Java中每个Key结构的内容,则一切都在这里。 请注意,当我将单个Key结构从Java传递到C时,有关设置为长值,为键的内容分配内存等的代码可以正常工作。因此,在这里,我通过使用指向指针的指针将数组传递给本机函数。数组的第一个元素:

instance.foo(keys[0].getPointer(), keys.length);

我的C函数当然是这样定义的:

void foo(key_t *keys, size_t count) {
  ...;
}

数组正确到达该位置:C端的keys指针与Java中的keys[0].getPointer()具有相同的地址,但不幸的是,数组中每个结构的成员均为0/NULL ,如GDB所指出的:

(gdb) print keys
$1 = (key_t *) 0x7fd7e82389e0
(gdb) print keys[0]
$2 = {length = 0, data = 0x0}

至此,我实在不知道发生了什么。 正如我所说,如果仅通过一种结构,它就可以正常工作,但是这里没有办法。 我可以看到的唯一区别是使用Pointer而不是Key[]的Java本机方法签名,但是当我使用数组时,我得到了:

IllegalArgumentException: [Lfoo.bar.Key; is not a supported argument type (in method foo ...

谢谢

如果传递Pointer值,则JNA不会知道实际上传递的是Structure还是它们的数组,并且要确保在本机调用之前调用Structure.write()并在其之后调用Structure.read()

如果您传递StructureStructure[] ,则JNA将自动处理同步。 对于Structure ,JNA使用内部簿记来确定您要传递的结构是否位于结构数组的开头。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM