JNA进阶应用,访问Union

Java想访问C代码编译的动态库,一般通过JNA方式实现,该方式好处是不用像JNI方式那样编写C wrapper代码,省去在Java工程里管理C代码的麻烦,但类型转换的坑却变多了。
最近在调试一款工业相机,它的主机接口有USB、GIGE、CameraLink等,SDK在枚举设备时会返回一个相机列表,每个表项都是一个相机,其类型按主机接口分类可能是上述3种任意一种,所以SDK一般都用联合体(Union)来表示,见下面结构体的SpecialInfo字段。

typedef struct _MV_CC_DEVICE_INFO_
{
    unsigned short      nMajorVer;
    unsigned short      nMinorVer;

    union
    {
        MV_GIGE_DEVICE_INFO stGigEInfo;
        MV_USB3_DEVICE_INFO stUsb3VInfo; 
        MV_CamL_DEV_INFO       stCamLInfo;
        // more ...
    }SpecialInfo;

}MV_CC_DEVICE_INFO;

应用程序想通过JNA读取nMajorVer字段,只需要cameraInfo.nMajorVer即可,但访问联合体却不像普通结构体那样简单,因为JNA的Union类JavaDoc里明确写着:

The current field is always unset by default to avoid accidentally attempting to read a field that is not valid.

即不告知JNA结构体的实际类型就读取的话,读到的永远是0

想读到有效值,需要

  1. cameraInfo.SpecialInfo.setType(MV_GIGE_DEVICE_INFO.class); // 设置这段内存实际存储的结构体类型
  2. cameraInfo.SpecialInfo.read(); // 按实际结构体类型反序列化这块内存段
  3. MV_GIGE_DEVICE_INFO gigeInfo = cameraInfo.SpecialInfo.stGigEInfo; // 按字段偏移读取结构体内的指定字段

如果只读取不写入,可以用一个快捷方法getTypedValue,下面代码先用getTypedValue提取结构体的内容,然后读取

MV_GIGE_DEVICE_INFO gigeInfo = (MV_GIGE_DEVICE_INFO)cameraInfo.SpecialInfo.getTypedValue(MV_GIGE_DEVICE_INFO.class);
byte[] rawCameraName = gigeInfo.chUserDefinedName;

相应的,如果只写入不读取,则用setTypedValue,用法类似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值