简体   繁体   English

如何在JNA结构中映射联合

[英]How to map a union in a JNA Structure

I need to convert a couple C structures to java using JNA. 我需要使用JNA将几个C结构转换为Java。 My structures are so composed: 我的结构是如此组成:

struct s_xl_event {
XLeventTag tag;
unsigned char chanIndex;
unsigned short transId;
unsigned short portHandle;
unsigned char flags;
unsigned char reserved;
XLuint64 timeStamp;
union s_xl_tag_data tagData;
};

union s_xl_tag_data {
struct s_xl_can_msg msg;
struct s_xl_chip_state chipState;
union s_xl_lin_msg_api linMsgApi;
struct s_xl_sync_pulse syncPulse;
struct s_xl_daio_data daioData;
struct s_xl_transceiver transceiver;
};

struct s_xl_can_msg {
unsigned long id;
unsigned short flags;
unsigned short dlc;
XLuint64 res1;
unsigned char data[MAX_MSG_LEN];
XLuint64 res2;
};

I added only the main structures that I needed but also because all the related structure are similar to s_xl_can_msg . 我仅添加了我需要的主要结构,还因为所有相关结构都与s_xl_can_msg相似。

In Java I did this using JNA: 在Java中,我使用JNA做到了这一点:

public static class s_xl_event extends Structure {
    public byte tag;
    public byte chanIndex;
    public short transId;
    public short portHandle;
    public byte flags;
    public byte reserved;
    public long timeStamp;
    public s_xl_tag_data tagData;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("tag","chanIndex","transId","portHandle","flags","reserved","timeStamp","tagData");
    }
}

public static class s_xl_tag_data extends Union {
    public s_xl_can_msg msg;
    public s_xl_chip_state chipState;
    public s_xl_lin_msg_api linMsgApi;
    public s_xl_sync_pulse syncPulse;
    public s_xl_daio_data daioData;
    public s_xl_transceiver transceiver;
}

public static class s_xl_lin_msg extends Structure {        
    public byte id;
    public byte dlc;
    public short flags;
    public byte[] data = new byte[8];
    public byte crc;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("id","dlc","flags","data","crc");
    }
}

When I use the method 当我使用方法

short xlReceive(long portHandle, IntByReference eventCount, s_xl_event eventList);

I obtain the values related to all the fields in s_xl_event except for tagData where all the fields are filled with 0. Now, I'm not sure that I mapped all the sub structures and unions as expected or I forgot something. 我获得了与tagData中所有字段相关的值,除了s_xl_event之外,其中所有字段均填充为0。 Has anyone had anything to do with such a thing? 有没有人与这样的事情有关?

When reading a Union like s_xl_tag_data , you must tell the Union which of its fields is being read by using setType() with either the class or field name, and then call read() on the Union. 当读取一个Unions_xl_tag_data ,你必须告诉联盟的哪个领域正通过读取setType()与任一类或字段名称,然后调用read()在联盟。

One way of doing this automatically when the parent structure is first populated is by overriding the read() method in the parent structure. 第一次填充父结构时自动执行此操作的一种方法是,重写父结构中的read()方法。

Add this method to your s_xl_event Structure: 将此方法添加到您的s_xl_event结构中:

public void read() {
    // read from native memory, populate tag
    super.read(); 
    // set union type based on tag
    switch(tag) {
    case XL_RECEIVE_MSG:
    case XL_TRANSMIT_MSG: 
        tagData.setType(s_xl_can_msg.class);
        break;
    case XL_CHIP_STATE: 
        tagData.setType(s_xl_chip_state.class);
        break;
    case XL_LIN_MSG: 
        tagData.setType(s_xl_lin_msg_api.class);
        break;
    // ... add other cases here...
    default:
        // add default type or throw exception etc.  
        break;
    }
    // now read tagData from native memory
    tagData.read();
}

As an alternative to passing the class to setType() for the union element, you could instead pass a String containing the variable name, eg, "msg" , "chipState" , or "linMsgApi" , etc. 作为将类传递给union元素的setType()的替代方法,您可以传递包含变量名称的String ,例如"msg""chipState""linMsgApi"等。

Also of note, the getFieldOrder() methods you are using in your Structure s are deprecated in the latest version of JNA. 还要注意,在最新版本的JNA中,不赞成在Structure中使用的getFieldOrder()方法。 You should use the @FieldOrder annotation instead. 您应该改用@FieldOrder批注。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM