java - JNA 从 void** 转换为结构

标签 java casting struct jna void

我必须调用一个 C 库,该库接收 void** 作为参数;它将 void** 转换为已知结构(取决于函数内部信息),然后分配内存并用数据填充它。

我不知道如何从 Java 调用它。

以下是一些详细信息:

结构:

typedef struct  { 
uint32_t   Size[64];  
uint16_t   *Datas[64]; 
} MyStruct_t;

C 函数

int Cfunc( void **Evt) {
  int i;
  MyStruct_t *s;
  s = (MyStruct_t *) malloc(sizeof(MyStruct_t));
  for (i=0; i<8; i++) {
    (s)->Size[i] = 512;
    (s)->Datas[i] = malloc(512 * sizeof (short));
  }
  for (i=8; i<63; i++) {
    (s)->Size[i] = 0;
    (s)->Datas[i] = NULL;
  }
*Evt = s;
}

我的 JNA 包装类:

public class MyStruct_t extends Structure<MyStruct_t, MyStruct_t.ByValue, MyStruct_t.ByReference > {
/// the number of samples stored in Datas array
public int[] Size = new int[64];
/// the array of Size samples
public ShortByReference[] Datas = new ShortByReference[64];
    public MyStruct_t() {
    super();
    initFieldOrder();
}
protected void initFieldOrder() {
    setFieldOrder(new String[]{"Size", "Datas"});
}
public MyStruct_t(int Size[], ShortByReference Datas[]) {
    super();
    if (Size.length != this.Size.length) 
        throw new IllegalArgumentException("Wrong array size !");
    this.Size = Size;
    if (Datas.length != this.Datas.length) 
        throw new IllegalArgumentException("Wrong array size !");
    this.Datas = Datas;
    initFieldOrder();
}
@Override protected ByReference newByReference() { return new ByReference(); }
@Override protected ByValue newByValue() { return new ByValue(); }
@Override protected MyStruct_t newInstance() { return new MyStruct_t(); }
public static MyStruct_t[] newArray(int arrayLength) {
    return Structure.newArray(MyStruct_t.class, arrayLength);
}
public static class ByReference extends MyStruct_t implements Structure.ByReference {};
public static class ByValue extends MyStruct_t implements Structure.ByValue {};
}

Java 函数声明:

public static native int Cfunc(MyStruct_t.ByReference Evt);
public static native int Cfunc(PointerByReference Evt);

如果我调用传递 PointerByReference 的 Cfunc,我可以看到内存已分配并且存在某些内容,但我不知道如何将其转换(?)到真实结构(MyStruct_t)。

如果我调用传递 MyStruct_t.ByReference 的 Cfunc,我会发现该结构分配不合理,并且内部的值不是预期的。 我做错了什么?

最佳答案

需要明确的是,您提供的是指针的地址。被调用者将指针值设置为它分配的结构的地址。

首先,传递指针的地址(又名 PointerByReference):

public static native int Cfunc(PointerByReference Evt);

然后,提取“返回的”指针值:

PointerByReference pref = new PointerByReference();
lib.CFunc(pref);
Pointer p = pref.getValue();

然后,您可以根据“返回”指针值创建结构的新实例:

MyStruct s = new MyStruct(p);

当然,这要求您为结构实现基于Pointer的构造函数:

public MyStruct(Pointer p) {
    super(p);
    read();
}

关于java - JNA 从 void** 转换为结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18876512/

相关文章:

c - 将 uint16_t 变量传递给期望 uint8_t 变量危险的函数

c++ - 构造函数中的模板类转换

c++ - 通过函数参数确定struct成员

java - 功能分解Java

java - 交叉检查两个 ArrayList 以查找包含某些单词的文本

c++ - 这是不可避免的有符号和无符号整数比较吗?

c - ((struct name *)0)->member) 在 C 中做什么?

java - 如何在 CardLayout 中显示特定的滚动 Pane ?

java - 如何从按钮javafx获取正确的文本值

c++ - 避免可变参数模板函数中的结构