通过JNA在Java中模拟联合体(Union)
在Java中调⽤动态链接库(.dll),不考虑性能的话⽤⽐⽤JNI要⽅便多了,只需要做数据映射之后再将导出函数声明⼀下就⾏了。下⾯分享⼀下通过JNA在Java中模拟联合体(Union)的经验。
⽰例来源于某CAN接⼝卡的:
typedef struct tagZCAN_CHANNEL_INIT_CONFIG {
UINT can_type;// 0:can 1:canfd
union
{
struct
{java jna
UINT acc_code;
UINT acc_mask;
UINT reserved;
BYTE filter;
BYTE timing0;
BYTE timing1;
BYTE mode;
}can;
struct
{
UINT acc_code;
UINT acc_mask;
UINT abit_timing;
UINT dbit_timing;
UINT brp;
BYTE filter;
BYTE mode;
USHORT pad;
UINT reserved;
}canfd;
};
}ZCAN_CHANNEL_INIT_CONFIG;
根据JNA的:
Unions are generally interchangeable with Structures, but require that you indicate which union field is active with the setType method before it can be properly passed to a function call.
我们在模拟联合体时需要⽤setType⽅法来指定激活哪⼀个字段。我个⼈的理解是由于Java中压根⼉就没有共⽤内存这种做法,所以通过不同内存上的字段来模拟,进⽽需要先告诉程序我们要⽤哪段内存(哪⼀个字段)。
注意:帮助⽂档中没有提及重写read和write⽅法,但这是必不可少的,并且setType⽅法就应该写在这俩⾥⾯。
下⾯给出相应的Java⽰例代码以供参考:
@Structure.FieldOrder({"can_type","cfg_union"})
public class ZCAN_CHANNEL_INIT_CONFIG extends Structure {
public int can_type;
public tagCfg_union cfg_union;
public static class ByValue extends ZCAN_CHANNEL_INIT_CONFIG implements Structure.ByValue{}
public static class ByReference extends ZCAN_CHANNEL_INIT_CONFIG implements Structure.ByReference{}
public static class tagCfg_union extends Union {
public tagCan can;
public tagCanfd canfd;
@Structure.FieldOrder({"acc_code","acc_mask","reserved","filter","timing0","timing1","mode"})
public static class tagCan extends Structure {
public int acc_code;
public int acc_mask;
public int reserved;
public byte filter;
public byte timing0;
public byte timing1;
public byte mode;
}
@Structure.FieldOrder({"acc_code","acc_mask","abit_timing","dbit_timing","brp","filter","mode","pad","reserved"}) public static class tagCanfd extends Structure {
public int acc_code;
public int acc_mask;
public int abit_timing;
public int dbit_timing;
public int brp;
public byte filter;
public byte mode;
public short pad;
public int reserved;
}
}
@Override
public void read(){
switch(can_type){
case0:
cfg_union.setType(tagCan.class);
break;
case1:
cfg_union.setType(tagCanfd.class);
break;
}
ad();
}
@Override
public void write(){
super.write();
switch(can_type){
case0:
cfg_union.setType(tagCan.class);
break;
case1:
cfg_union.setType(tagCanfd.class);
break;
}
cfg_union.write();
}
}
类命名不规范(有的⾸字母未⼤写),请忽略,hh

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。