2015-02-23 12 views
7

Tôi sẽ viết lại mã C thành Java. Cốt lõi của mã C ban đầu là một trình bao bọc HW. Trong C, chúng tôi đã sử dụng rất nhiều các đoàn thể đối với từng HW đăng ký ví dụ:cách viết nhiều công đoàn nhỏ từ C vào Java

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; 

thì chúng ta sử dụng nó như

regABC r; 
r.reg=0 
r.bits.bit0_abc=1; 
call(r.reg) 

tưởng tượng có rất nhiều những thanh ghi. Hãy nói rằng 40. Làm thế nào để thực hiện nó vào java không có 40 tập tin lớp học? Tôi đã suy nghĩ để tạo ra một lớp như

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; 
    } 
} 

sau đó một tập tin có thể chứa nhiều enums như:

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

sau đó tôi sẽ sử dụng nó như:

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

Nhưng nó không hoạt động bởi vì có vẻ như tôi không thể sử dụng biến enum .v trong univerasl_reg. Nó mang lại "Java canot tìm biểu tượng v". Bạn có biết tại sao? Bạn có biết làm thế nào để mã đăng ký để có
- tốt nhất là một tập tin
- kiểm soát loại giữa thanh ghi khác nhau (ví dụ

new univerasl_reg<RegTst>.set(RegTst_OTHER.b2_xyz,1)
sẽ dẫn đến lỗi như tôi không sử dụng RegTst nhưng RegTst_OTHER)
- và ghi nhớ cho bit (ví dụ: RegTst.b1_abc)

+0

Bạn có xem xét một 'HashMap '? – vikingsteve

+0

có vẻ thú vị nhưng không may, phong cách của java không có ma thuật. chung trong java, tôi nên nói, nó sucks. về cơ bản, tất cả các loại trong generics sẽ dẫn đến 'Object' cuối cùng. có lẽ tôi không hiểu vấn đề của bạn đủ tốt, nhưng có 40 tập tin lớp có thể là giải pháp thích hợp nhất nếu bạn có 40 'struct' tương ứng trong c. – HuStmpHrrr

+0

@HuStmpHrr: có 40 lớp là một tùy chọn. Nhưng tôi nghĩ rằng enums là phù hợp hơn và giải pháp từ Marko Topolink cho phép tôi sử dụng giá trị của enum. –

Trả lời

2

Java Generics là một tính năng của hệ thống kiểu tĩnh. Khi bạn chấp nhận bất kỳ T nào cho thông số loại, hệ thống kiểu tĩnh không có cơ sở để kết luận rằng loại này có một biến cá thể v. Sự lựa chọn của bạn về enums làm phức tạp thêm nhiều thứ bởi vì enums không thể có một siêu lớp tùy ý.

tôi xin đề nghị như sau:

  1. dựa trên đa hình và ẩn đằng sau v một phương pháp ;
  2. khai báo giao diện với phương thức này;
  3. làm cho tất cả các enums triển khai giao diện;
  4. sử dụng giao diện làm giới hạn trên trên T.

Trong mã:

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; } 
} 
+0

Cảm ơn bạn! Làm việc như quyến rũ.Bạn đã tiết kiệm cho tôi rất nhiều thời gian cos như một newbie tôi không biết . Tôi đã thử siêu lớp trước nhưng như bạn đã đề xuất nó không biên dịch cho tôi. –

Các vấn đề liên quan