1

我必须在跨越多个 DWORDS 的位域中编写独立位。我目前使用的结构如下

typedef struct _myStruct
{
    union 
    {
        struct 
        {
            DWORD   field1       : 16
            DWORD   field2       : 8
            DWORD   field3       : 8
        };
        DWORD   value0;
    };
    union 
    {
        struct 
        {
            DWORD   field4       : 32; 
        } 
        DWORD   value1;
    };
} myStruct;

我这样做是为了让程序员可以直接访问独立的字段,而不是记住相应的 DWORD 即myStruct.field1等。这在 Visual Studio 中运行良好,但是当我使用未命名的结构和联合时 GCC 会抱怨。为了纠正这个问题,我尝试如下命名联合和结构:

    union _DW0
    {
        struct _BF
        {
            DWORD   field1       : 16
            DWORD   field2       : 8
            DWORD   field3       : 8
        } BF;
        DWORD   value0;
    } DW0;

但是现在访问对程序员不友好.. 即尝试对此进行编程的人必须记住每个字段属于哪个 DWORD。例如:myStruct.DW0.field1

有没有办法解决这个问题?

4

2 回答 2

1

位域本质上是不可移植的。当你编写DWORD field1 : 16;标准时并没有确定是否field1应该具有结构的高位或低位 16 位。另一方面,如果您使用正确的类型和联合(在您的情况下就足够了,因为您的所有位域都与大多数平台中的类型匹配),那么它可以是可移植的。

使用 C++11 类型(您也可以使用具有适合您平台的类型的库):

union {
   struct {
      uint16_t  _1;
      uint8_t   _2;
      uint8_t   _3;
   } field;
   uint32_t value;
};
// ...
于 2012-08-25T02:04:53.213 回答
0

匿名联合通常是可以的,但结构需要有一个名称。您可以使用它从语法中删除一级“点”。

但是,如果您需要通过命名结构成员单独(作为位域)和作为一个整体(作为 DWORDS)访问字段,那么您将不得不使用稍微混乱的语法。这种用例需要联合,这需要内部结构,这会导致问题。您总是可以隐藏 getter/setter 函数后面的所有杂乱语法,但如果结构很大,那么该方法将不是很容易维护。

这是您可以考虑的替代方案:

typedef struct
{
    // DWORD 0
    DWORD   field1   : 16;
    DWORD   field2   : 8;
    DWORD   field3   : 8;
    // DWORD 1
    DWORD   field4   : 32; 
} bitfield_struct;

这只会为您提供位域级别的访问权限,但语法更简洁。如果需要,您仍然可以访问 DWORD 级别的数据,但是:

bitfield_struct foo;
DWORD* bar = (DWORD*)&foo;

bar[0] = ...;
bar[1] = ...;

如果您通常通过位域访问数据并且很少通过 DWORD 访问数据,那么这可能是一个可以接受的解决方案。

于 2012-08-25T00:44:28.707 回答