将c联合映射到java

时间:2017-06-14 17:06:06

标签: java c java-native-interface

我在c

中有这个结构

    typedef struct {
        uint32_t id;
        uint32_t dateTime;
        uint32_t deviceID;
        union {
            char userID[BS2_USER_ID_SIZE];
            uint32_t ioDeviceID;
        };
        union {
            uint16_t code;
            struct {
                uint8_t mainCode;
                uint8_t subCode;
            };
        };
        uint8_t param;
        uint8_t image;
    } BS2Event;

这个用于映射struct的java类:


    public class BS2Event extends Structure{
    public int id;
        public int dateTime;
        public int deviceID;

        public int param;
        public int image;
    }

如何在映射java类中映射联合?

2 个答案:

答案 0 :(得分:2)

Java不允许多个字段占用相同的内存。 Java中没有C union的直接类比。所以你不能:

  • 通过让多个字段占用相同的空间来节省内存,而在任何给定时间只有一个适合。
  • 仅通过访问联合中的另一个字段来访问不同表示形式的一个存储值(因为您的第二个联合似乎是预期的)。即使在C ++中,这是技术上未定义的行为,尽管有些编译器支持它。

也就是说,可以将包含C联合的代码转换为Java代码。

多个字段,未保存在同一内存中

一种方法是在一个类中有多个字段。将为每个字段分配内存,即使最多只能使用一次。

public class BS2Event {
    ...
    // Only one of these can be set
    char[] userID = new char[BS2_USER_ID_SIZE];
    int ioDeviceID;
    ...
}

基类或接口类型的单个字段

另一种方法是使用引用一个当前表示的单个Object或接口指针来表示联合。内存仅在类中为单个引用分配,但引用的对象需要额外的内存。

public class BS2Event {
   // Ordinary struct fields 
   ...
   private IEntityID m_userOrDeviceID;
   ...
}

现在,m_userID可以指向UserID或DeviceID。

public interface IEntityID { ... }

public class UserID implements IEntityID {
   private char[] userID = new char[BS2_USER_ID_SIZE];
   ...
}

private class DeviceID implements IEntityID {
   private int ioDeviceID;
   ...
}

一种表示形式,以多种方式访问​​

如果您想以多种方式访问​​一个表示,则可以使用方法而不是字段来执行此操作。

public class BS2Event {
   // Ordinary struct fields 
   ...
   private Code m_code;
   ...
}

private class Code {
   private int code;
   public int getCode() { return code; }
   public short getMainCode() { ... }
   public short getSubCode() { ... }
}

答案 1 :(得分:0)

您可以使用以下方法直接映射结构: http://javolution.org/apidocs/javolution/io/Struct.html 它工作得很好(支持压缩结构,不同的字节顺序)。