C中的结构包装

时间:2013-08-14 18:41:48

标签: c++ c structure qt-creator

我有一个结构:

**struct PROCESSING
{
    PROCESSOR Byte ;
    uint16_t count ;
    uint8_t overrange ;
    Status status ;
    Time timestamp ;
    float Field;
    float temperature ;
    float adc1;
    float dac1;
    float Field2;
    float Temperature;
    float adc2 ;
    float dac2 ;
};
PTC_STATIC_ASSERT_SIZE(Processing, 45U);**

这个结构实际结构是45U,但是当我构建时我得到一个错误:
“sizeof到不完整类型的应用无效”

我需要把它打包到45U。

2 个答案:

答案 0 :(得分:0)

关于结构包装:

为了避免对齐和填充问题,您应该考虑。

  • 重新安排成员。

  • 自己添加填充。

  • 告诉编译器将每个成员的边界更改为1个字节。

例如:

#pragma pack(push)
#pragma pack(1)
struct PROCESSING
{
    PROCESSOR Byte ;
    uint16_t count ;
    uint8_t overrange ;
    Status status ;
    Time timestamp ;
    float Field;
    float temperature ;
    float adc1;
    float dac1;
    float Field2;
    float Temperature;
    float adc2 ;
    float dac2 ;
};
#pragma pack(pop)

重新对齐以防止填充。

struct PROCESSING
{
    PROCESSOR Byte ; // 1 byte
    Status status ;  // 1 byte
    char __padding[2]; // 2 bytes

    uint16_t count ;   // 2 byte
    uint8_t overrange ; // 1 byte
    char _padding;      // 1 byte

    Time timestamp ; // 8 bytes

    float Field;
    float temperature ;
    float adc1;
    float dac1;
    float Field2;
    float Temperature;
    float adc2 ;
    float dac2 ;
};

标准保证默认不会应用填充!
你应该确定一件事。 不会 在结构的开头是任何填充,之后你就是你自己的 - 默认 - 。

答案 1 :(得分:0)

我没有了解如何定义所有用户定义类型的好处,但您的直接问题似乎是您的PROCESSING结构不是完全定义的。也许你错过了一个合适的头文件或其他东西的#include。一旦解决了,如果你需要更多关于编译器如何在内存中放置结构的信息,你可能会创建一些临时调试代码,如下所示(请注意,我已经冒昧地添加了类型的定义,这可能是不符合你自己的定义)....

typedef char PROCESSOR;
typedef char Status;
struct Time
{
char t[8];
};


struct PROCESSING
{
    PROCESSOR Byte ;
    uint16_t count ;
    uint8_t overrange ;
    Status status ;
    Time timestamp ;
    float Field;
    float temperature ;
    float adc1;
    float dac1;
    float Field2;
    float Temperature;
    float adc2 ;
    float dac2 ;
};


int main()
{
    PROCESSING p;

    printf("Member          Size  Offset\n"
        "-------------- ------ ------\n");

    #define MACROS_MAKE_THE_WORLD_GO_AROUND(structMember) \
            printf("%14s ", #structMember); \
            printf(" %3d ", sizeof(p.structMember)); \
            printf("  %3d\n", offsetof(PROCESSING,structMember));

    MACROS_MAKE_THE_WORLD_GO_AROUND(Byte)
    MACROS_MAKE_THE_WORLD_GO_AROUND(count)
    MACROS_MAKE_THE_WORLD_GO_AROUND(overrange)
    MACROS_MAKE_THE_WORLD_GO_AROUND(status)
    MACROS_MAKE_THE_WORLD_GO_AROUND(timestamp)
    MACROS_MAKE_THE_WORLD_GO_AROUND(Field)
    MACROS_MAKE_THE_WORLD_GO_AROUND(temperature)
    MACROS_MAKE_THE_WORLD_GO_AROUND(adc1)
    MACROS_MAKE_THE_WORLD_GO_AROUND(dac1)
    MACROS_MAKE_THE_WORLD_GO_AROUND(Field2)
    MACROS_MAKE_THE_WORLD_GO_AROUND(Temperature)
    MACROS_MAKE_THE_WORLD_GO_AROUND(adc2)
    MACROS_MAKE_THE_WORLD_GO_AROUND(dac2)

    #undef MACROS_MAKE_THE_WORLD_GO_AROUND

    printf("\n   Total size of PROCESSING struct: %d bytes\n\n", sizeof(p));
}

当你运行它时,你会看到类似这样的东西:

Member          Size  Offset
-------------- ------ ------
          Byte    1     0
         count    2     2
     overrange    1     4
        status    1     5
     timestamp    8     6
         Field    4    16
   temperature    4    20
          adc1    4    24
          dac1    4    28
        Field2    4    32
   Temperature    4    36
          adc2    4    40
          dac2    4    44

   Total size of PROCESSING struct: 48 bytes

一旦你有了这个,你就可以开始弄清楚你需要做些什么来使你的结构与嵌入式系统的结构布局相匹配,这可能比简单地使结构整体尺寸相同。但#pragma暗示其他人给出的可能是一个好的开始。注意编译器添加的填充,你可以通过添加'size'列和&将它与'offset'列进行比较,如果它们不匹配,你知道编译器插入了一些填充。