简体   繁体   中英

How to represent this in Java

typedef struct _dmk {
       unsigned short int m     : 5;    // 0 - 31  
       unsigned short int d     : 5;    // 0 - 31  
       unsigned short int c     : 1;    // 0 - 1   
       unsigned short int i     : 5;    /* 0 - 31 */
       unsigned short int ip    : 10;   /* 0 - 1024 */
       unsigned short int mj    : 1;    // 0 - 1
       unsigned short int       : 5;    /* unused */ 
       char    msk[10];
    } DMSK;

What does the: represent here? Should I use byte data type or short will be fine? Also in the last unsigned short int declaration there is no variable name specified. What does that mean? What is the significance of 5, 5, 1, 5....? Please explain. Thanks

Those are bit fields in C. This structure's going to be nearly impossible to represent as is in Java. You'd have to write methods to access the individual bits, although you could just expose the underlying int.

Just use the Java way, like getM() and setM() . Of course you have to write teir code.

Your structure describes a bit table. The first 5 bits contain the field m the next 5 bits (crossing the byte boundary) contains d and so on.

JFC (the Java API) has no implementation which can help you, so if you use structures like this often in your program I recommend writing a class like SlidingInteger which can handle a single field. Like this:

class DMK {
    private static final int FIELD_M = 0;
    private static final int FIELD_D = 1;
    private static final int FIELD_C = 2;
    private static final int FIELD_I = 3;
    private static final int FIELD_IP = 4;
    private static final int FIELD_MJ = 5;
    private static final int FIELD_PLACEHOLDER1 = 6;

    private SlidingInteger[] fields;

    public DMK() {
        fields = new SlidingInteger[7];
        fields[FIELD_M] = new SlidingInteger(5);
        fields[FIELD_D] = new SlidingInteger(5);
        fields[FIELD_C] = new SlidingInteger(1);
        fields[FIELD_I] = new SlidingInteger(5);
        fields[FIELD_IP] = new SlidingInteger(10);
        fields[FIELD_MJ] = new SlidingInteger(1);
        fields[FIELD_PLACEHOLDER1] = new SlidingInteger(1);
    }

    public int getM() {
        return fields[FIELD_M].getIntValue();
    }

    public int setM(int newVal) {
        fields[FIELD_M].setIntValue(newVal);
    }

    public int getD() {
        return fields[FIELD_D].getIntValue();
    }

    public int setD(int newVal) {
        fields[FIELD_D].setIntValue(newVal);
    }
}

Class Struct from Javolution library makes what you need ( http://www.javolution.org/apidocs/index.html?javolution/io/Struct.html ) See "Clock" example:

 import java.nio.ByteBuffer;
 class Clock extends Struct { // Hardware clock mapped to memory.
     Unsigned16 seconds  = new Unsigned16(5); // unsigned short seconds:5
     Unsigned16 minutes  = new Unsigned16(5); // unsigned short minutes:5
     Unsigned16 hours    = new Unsigned16(4); // unsigned short hours:4
     Clock() {
         setByteBuffer(Clock.nativeBuffer(), 0);
     }
     private static native ByteBuffer nativeBuffer();
 }

It denotes the number of bits the unsigned int takes.

For m, d, c, i, mj you can use byte (8bit max) data type (you can also use c as a boolean), but ip requires at least a short (16bit max).

This is a way to pack data to specific number of bits, to perhaps save a very small amount of space.

You would have to use the next larger types, 8 or 16 bits wide.

The element without a name is just explicit padding. The number of bits specified is skipped, and not really needed here as the next element would be byte aligned anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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