如何将 C 中的许多小联合写入 Java

how to write lots of small unions from C into Java

我要把C代码重写成Java。原始 C 代码的核心是硬件包装器。在 C 中,我们为每个 HW 寄存器使用了很多联合,例如:

typedef union RegIntStatus
{
   u8 reg;
   struct
   {
      u8 bit0_abc:1;
      u8 bit1_cde:1;
      u8 bit2_xyz:1;
      u8 bit3_7_rsvd:5;
   } bits;
} regABC;

然后我们像

一样使用它
regABC r;
r.reg=0
r.bits.bit0_abc=1;
call(r.reg)

想象一下有很多这样的寄存器。比方说 40。如何将它实现到 java 而不是 40 class 个文件?我想创建一个 class 像

univerasl_reg<T> { // where T will be some "enum"
  public byte b;
  public byte set(T bit_mask,bool val) {
    // here is compile error it does not know variable bit_mask.v
    if(val) {b |= bit_mask.v}     
    else b &= bit_mask.v ^ 0xFF;
  }
}

然后一个文件可以包含多个枚举,例如:

public static enum RegTst{
        b1_abc(0x01),
        b2_xyz(0x02),
        b3_klm(0x04);
        public byte v;
        RegTst(int val){
            v = (byte)val;
        }
    }

那么我会像这样使用它:

univerasl_reg<RegTst> rt1;
rt1.set(RegTst.b2_xyz,1)
call(rt1.b)

但它不起作用,因为我似乎无法在 univerasl_reg 中使用枚举变量 .v。它产生 "Java canot find symbol v"。你知道为什么吗? 你知道如何对寄存器进行编码以便
- 最好是一个文件
- 不同寄存器之间的类型控制(例如

new univerasl_reg.set(RegTst_OTHER.b2_xyz,1)
会导致错误,因为我没有使用 RegTst 但 RegTst_OTHER)
- 和位的助记符(例如 RegTst.b1_abc)

Java 泛型只是静态类型系统的一个特性。当你为类型参数接受任何 T 时,静态类型系统没有根据断定此类型具有实例变量 v。您对枚举的选择使事情变得更加复杂,因为枚举不能具有任意超类。

我建议如下:

  1. 依赖多态性并隐藏v方法;
  2. 后面
  3. 用这个方法声明一个接口;
  4. 使所有枚举实现接口;
  5. 使用接口作为 T 的上限。

在代码中:

public interface Mask {
   byte v();
}

public class UniversalReg<T extends Mask> {
  public byte b;
  public byte set(T mask, boolean val) {
     if (val) b |= mask.v();
     else b &= ~mask.v();
  }
}

public enum RegTst implements Mask {
    b1_abc(0x01),
    b2_xyz(0x02),
    b3_klm(0x04);

    private final byte v;
    private RegTst(int val) {
        v = (byte)val;
    }

    @Override public byte v() { return v; }
}