考虑我有以下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
的{{1}}字段明确地为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
字段的字段不正确。为什么会这样?
答案 0 :(得分:1)
请勿使用Structure.ByValue
。 JNA假定以值结构语义开始于结构类型字段; Structure.ByValue
标记实际上触发了特殊处理,它假设(可能过于宽泛地)它正在处理按值函数参数或返回值。