Java JNA标记的联合映射
如何将以下“标记的联合”结构映射到JNA?此结构由Java JNA标记的联合映射,java,jna,Java,Jna,如何将以下“标记的联合”结构映射到JNA?此结构由libvterm()使用 尽管有许多映射可以工作(任何32位结构都使用正确的方法来获取值),但直接映射的规范方法是使用JNA的类。欧盟将有三个要素;您可以定义的字节,或结构RGB(联合的内部类可以),或将定义的结构索引(同样,内部类) 联合将在本机端为最大元素(32位)分配足够的内存,并且给定结构选项,可以保证生成的32位C端内存的前8位将包含类型字段;根据该值,您将知道剩余24位中包含的内容 如果您查看映射,您将看到它是以稍微复杂的比例实现的。
libvterm
()使用
尽管有许多映射可以工作(任何32位结构都使用正确的方法来获取值),但直接映射的规范方法是使用JNA的类。欧盟将有三个要素;您可以定义的
字节
,或结构RGB(联合的内部类可以),或将定义的结构索引(同样,内部类)
联合
将在本机端为最大元素(32位)分配足够的内存,并且给定结构选项,可以保证生成的32位C端内存的前8位将包含类型
字段;根据该值,您将知道剩余24位中包含的内容
如果您查看映射,您将看到它是以稍微复杂的比例实现的。\u VARIANT
类包含以下五个元素,与联合体中的三个元素类似:
public VARTYPE vt;
public short wReserved1;
public short wReserved2;
public short wReserved3;
public __VARIANT __variant;
对于联合,只有一个\u variant
值有效。在这种情况下,类型设置如下:
public void setVarType(short vt) {
this._variant.vt = new VARTYPE(vt);
}
更一般地说,您可以查看外部VARIANT
类,该类使用Union类setType()
方法来确定是否存在有效值:它设置了一个与构造函数中设置的活动字段(在本例中为“\u VARIANT”
)对应的字符串。(也可以使用类而不是字符串进行设置。)
在您的情况下,您需要基于类型值进行初始化,因此您将以类型作为默认值,读取其值,然后切换
您可以这样定义您的工会:
public class VTermColor extends Union {
public class RGB extends Structure {
public byte type;
public byte red;
public byte green;
public byte blue;
}
public class Indexed extends Structure {
public byte type;
public byte idx;
}
public byte type;
public RGB rgb;
public Indexed indexed;
public VTermColor() {
// initialize knowing only the type, read its value
this.setType("type");
this.read();
// switch union based on type, re-read
if ((this.type & VTERM_COLOR_TYPE_MASK) == VTERM_COLOR_RGB) {
this.setType("rgb");
} else {
this.setType("indexed");
}
this.read();
}
public VTermColor(Pointer p) {
super(p);
// same remaining code as above
}
}
在返回相应字段之前,您可能需要创建一些其他getter方法来检查类型
值
正如一开始提到的,任何32位数据结构都可以工作。一个有点黑的替代方案(牺牲可读性和类型安全性来换取少得多的代码)可以简单地始终使用上面定义的4字节RGB
结构。类型
的getter始终有效,而红色
、绿色
和蓝色
的getter如果有效则有效,否则您可以为idx
创建一个getter,该getter只读取红色
的值
public class VTermColor extends Union {
public class RGB extends Structure {
public byte type;
public byte red;
public byte green;
public byte blue;
}
public class Indexed extends Structure {
public byte type;
public byte idx;
}
public byte type;
public RGB rgb;
public Indexed indexed;
public VTermColor() {
// initialize knowing only the type, read its value
this.setType("type");
this.read();
// switch union based on type, re-read
if ((this.type & VTERM_COLOR_TYPE_MASK) == VTERM_COLOR_RGB) {
this.setType("rgb");
} else {
this.setType("indexed");
}
this.read();
}
public VTermColor(Pointer p) {
super(p);
// same remaining code as above
}
}