1

我有一个二维整数数组(8x8),其中每个“行”都包含一条接收到的消息。我有兴趣将这个数组的元素incomingMessageBuffers[1][0:7] 映射到一个具有定义位域的结构中,这可能比使用掩码和移位方法更快。我知道位域排序取决于编译器,但无论如何我都想了解为什么我会看到观察到的行为,因为我认为它与这个事实无关。

我试图映射到 MYSTRUCT 的内存

 - incomingMessageBuffer [1][0:7]  
    0. 0x1544 
    1. 0x0000 
    2. 0x0008 
    3. 0x3400 
    4. 0x0012 
    5. 0x8100 
    6. 0x0000 
    7. 0x0000

神秘的定义:

struct MYSTRUCT{
   unsigned int PACKET0:16;
   unsigned int PACKET1:16;
   unsigned int PACKET2:16;

   unsigned char PACKET3_LOW:8;
   unsigned int MYINTEGER:16;
   unsigned char PACKET4_HIGH:8;

   unsigned char PACKET5_LOW:8;
   unsigned char MYBIT:1;
   unsigned char EXTRABITS:3;
   unsigned char MYNIBBLE:4;

   unsigned int PACKET6:16;
   unsigned int PACKET7:16; }

我的映射代码和所需结果的示例:

volatile struct MYSTRUCT *Message           
Message = &incomingMessageBuffer[1][0];     

myInteger = (Message->MYINTEGER);           
myBit = (Message->MYBIT);       
myNibble = (Message->MYNIBBLE);

Expected values:
myInteger = 0x1234
myBit = 0x01;
myNibble = 0x08;

相反,这会正确映射到 PACKET0、1 和 2,但以下成员分配不正确。根据我对此类定义的约定的理解......

struct
{
    type [member_name] : width ;
};

type 定义 member_name 类型(即 PACKET6、MYBIT 等),如果类型大小大于宽度,则 member_name 中的额外高位将用零填充。我想这是不正确的,因为除非我这样定义我的结构,否则我看不到分配的预期值:

struct MYSTRUCT_2{
    unsigned int PACKET0:16;
    unsigned int PACKET1:16;
    unsigned int PACKET2:16;

    unsigned char PACKET3_LOW:8;
    unsigned long int MYINTEGER:16; //Notice long int here
    unsigned char PACKET4_HIGH:8;

    unsigned char PACKET5_LOW:8;
    unsigned char MYBIT:1;
    unsigned char EXTRABITS:3;
    unsigned char MYNIBBLE:4;

    unsigned int PACKET6:16;
    unsigned int PACKET7:16;
}

然后使用结构成员的掩码分配我的变量:

volatile struct MYSTRUCT *Message           
Message = &incomingMessageBuffer            

myInteger = (Message->MYINTEGER)&0xFFFF         
myBit = (Message->MYBIT)&0x01           
myNibble = (Message->MYNIBBLE)&0x0F         

那么,如果仅定义 MYINTEGER 的大小,为什么将 MYINTEGER 声明为 unsigned long int 会导致按照位映射进行正确分配?

任何帮助深表感谢。

4

1 回答 1

0

我相信这个问题可能是由于我的第一个结构中的整数定义未对齐。其中对齐需要整数的第一位被定义为 16 的倍数。

那样...

struct MYSTRUCT{
   unsigned int PACKET0:16;
   unsigned int PACKET1:16;
   unsigned int PACKET2:16;

   unsigned char PACKET3_LOW:8;   
   unsigned char PACKET4_HIGH:8;
   unsigned int MYINTEGER:16;

   unsigned char PACKET5_LOW:8;
   unsigned char MYBIT:1;
   unsigned char EXTRABITS:3;
   unsigned char MYNIBBLE:4;

   unsigned int PACKET6:16;
   unsigned int PACKET7:16; }

...工作,因为 MYINTEGER 出现在两个 char 定义之后,每个定义都映射到结构中的 8 位。然而,使用相同的逻辑,我不明白为什么将其声明为 long int 会解决问题。

于 2013-11-15T00:20:52.350 回答