[英]JNA cast to struct from void**
我必須調用一個C庫,該庫接收void**
作為參數。 它將void**
轉換為已知結構(取決於函數內部信息),然后分配內存並用數據填充它。
我不知道如何從Java調用它。
以下是一些詳細信息:
typedef struct {
uint32_t Size[64];
uint16_t *Datas[64];
} MyStruct_t;
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;
}
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 {};
}
public static native int Cfunc(MyStruct_t.ByReference Evt);
public static native int Cfunc(PointerByReference Evt);
如果我通過PointerByReference調用Cfunc,則可以看到已分配內存並且存在某些內容,但是我不知道如何將其轉換為真實結構(MyStruct_t)。
如果我通過MyStruct_t.ByReference
調用MyStruct_t.ByReference
,則發現結構分配不MyStruct_t.ByReference
,並且內部的值不是預期的。 我究竟做錯了什么?
需要明確的是,您正在提供一個指針的地址。 被調用者將指針值設置為它分配的結構的地址。
首先,傳遞指針的地址(又名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
的ctor:
public MyStruct(Pointer p) {
super(p);
read();
}
我發現了錯誤! 我從jnaerator使用Structure類,刪除了jnaerator Structure類並使用了JNA Structure,現在它可以工作了。
這是經過修改且可以正常工作的java類:
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.ShortByReference;
public class t_t extends Structure {
public int[] lsize = new int[64];
public Pointer[] ldata = new Pointer[64];
public t_t() {
super();
initFieldOrder();
}
protected void initFieldOrder() {
setFieldOrder(new String[]{"size", "data"});
}
public t_t(int size[], Pointer data[]) {
super();
if (size.length != this.lsize.length)
throw new IllegalArgumentException("Wrong array size !");
this.lsize = size;
if (data.length != this.ldata.length)
throw new IllegalArgumentException("Wrong array size !");
this.ldata = data;
initFieldOrder();
}
public t_t(Pointer p){
super(p);
read();
}
public short[] getData(int i) {
if (this.lsize[i] == 0) return null;
return this.ldata[i].getShortArray(0, this.lsize[i]);
}
public int getSize(int i) {
return this.lsize[i];
}
public static class ByReference extends t_t implements Structure.ByReference {
};
public static class ByValue extends t_t implements Structure.ByValue {
};
}
感謝技術專家的提示! p1906
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.