次の 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;
sa
C 関数に渡します。
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
は正しくありません。なぜこうなった?