1

パラメータとして a を受け取る 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) にキャスト (?) する方法がわかりません。

を渡して Cfunc を呼び出すとMyStruct_t.ByReference、構造体が適切に割り当てられておらず、内部の値が期待どおりではないことがわかります。私は何を間違っていますか?

4

2 に答える 2

2

明確にするために、ポインタのアドレスを提供しています。呼び出し先は、ポインター値を、割り当てた構造体のアドレスに設定します。

最初に、ポインターのアドレス (aka 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();
}
于 2013-09-18T17:10:52.250 に答える
0

間違いを見つけました!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

于 2013-09-19T09:54:55.987 に答える