次の 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は正しくありません。なぜこうなった?