0

次の C 構造体定義があるとします。

struct StructB {
    int a;
    int b;
};

struct StructA {
    struct StructB *ref;
    struct StructB value;
};

Java では次のように表されます。

public class StructA extends Structure implements Structure.ByReference {
    public StructB.Reference ref;
    public StructB value;

    public StructA() {
        ref = new StructB.Reference();
    }

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"ref", "value"});
    }
}

public class StructB extends Structure {
    public static class Reference extends StructB implements Structure.ByReference { }
    public int a;
    public int b;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"a", "b"});
    }
}

Java で新しいオブジェクトを割り当て、StructAそのフィールドを次のように設定する場合:

StructA sa = new StructA();
sa.ref.a = 1;
sa.ref.b = 2;
sa.value.a = 3;
sa.value.b = 4;

saC 関数に渡します。

void printnest(struct StructA *s) {
    printf("Printing structA...\n");
    printf("\ts->ref->a: %d\n", s->ref->a);
    printf("\ts->ref->b: %d\n", s->ref->b);
    printf("\ts->value.a: %d\n", s->value.a);
    printf("\ts->value.b: %d\n", s->value.b);
}

次の出力が得られます。

Printing structA...
    s->ref->a: 1
    s->ref->b: 2
    s->value.a: 3
    s->value.b: 4

どちらが正しい。

ただし、次のように内部で別の静的クラスを宣言するとStructB:

public class StructB extends Structure {
    public static class Reference extends StructB implements Structure.ByReference { }
    public static class Value extends StructB implements Structure.ByValue { }
    public int a;
    public int b;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"a", "b"});
    }
}

valueのフィールドStructAを明示的に次のように宣言しますStructure.ByValue

public class StructA extends Structure implements Structure.ByReference {
    public StructB.Reference ref;
    public StructB.Value value;

    public StructA() {
        ref = new StructB.Reference();
    }

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"ref", "value"});
    }
}

次の出力呼び出しが再びprintnest渡されます。sa

Printing structA...
    s->ref->a: 1
    s->ref->b: 2
    s->value.a: 0
    s->value.b: 0

したがって、フィールドのStructB.ValueフィールドStructAは正しくありません。なぜこうなった?

4

1 に答える 1

1

使用しないでくださいStructure.ByValue。JNA は、構造型フィールドの最初から値によるセマンティクスを想定しています。タグは実際には、Structure.ByValue値渡しの関数パラメーターまたは戻り値を処理していると想定する (おそらく過度に広範に) 特別な処理をトリガーします。

お気軽に問題を提出してください。

于 2013-07-17T11:42:50.503 に答える