【问题标题】:Casting pointer to reuse a buffer转换指针以重用缓冲区
【发布时间】:2013-04-25 14:08:37
【问题描述】:

那里: 我有这样的声明:

typedef struct
{
    quint8  mark1;
    quint16 content1;
    quint16 content2;
    quint8  mark2;
}FrameHead;

在函数中,我定义了一个缓冲区,并对其赋值:

quint8 buf[40];
FrameHead *frame  = (FrameHead *)buf;
frame->mark1 = 0x68;
frame->content1 = 0x3A;
frame->content1 = 0x3A;
frame->mark2 = 0x68;

所以我想,buf的前6个字节应该是“68 3A 00 3A 00 68”。但事实是,buf的前8个字节是“68 90 3A 00 3A 00 68 80”。我用过:

qDebug() << (quint8 *)(++frame) - buf// output "8" but should be "6"

似乎数字“0x68”不是存储为 quint8 类型而是 quint16 类型以保持与其他 quint16 类型的一致性。任何人都遇到过同样的问题,有什么建议。

【问题讨论】:

    标签: c++ casting struct alignment packet


    【解决方案1】:

    这是由于对齐。 16 位类型在 16 位地址上对齐。由于您的第一个成员仅使用 8 位,因此插入了 1 个字节填充。

    如果您将结构重新排序为

    typedef struct
    {
        quint8  mark1;
        quint8  mark2;
        quint16 content1;
        quint16 content2;
    }FrameHead;
    

    它将仅使用 6 个字节,因为对齐 content1 不需要填充。

    请参阅Structure padding and packing 以获得更详细的说明。

    评论后编辑:

    所以要么你使用#pragma pack(1)(见:http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=VS.100%29.aspx)(不知道你的意思

    在 Qt 中设置对齐方式,如 VC 中的“#Pragma””

    ) 或者你只是使用一个数组:

    typedef quint[6] FrameHead;
    
    ....
    
    FrameHead fh1 = {0x68, 0x00, 0x00, 0x00, 0x00, 0x68};
    // or 
    FrameHead fh2;
    memset( fh2, 0, sizeof(FrameHead));
    fh2[0] = 0x68;
    fh2[5] = 0x68;
    

    【讨论】:

    • 感谢 johannes S. 但我需要格式化“buf”。数据包的开始字节和结束字节应该是“0x68”,这就是为什么我在结构中间插入“contents1”,“contents2”。现在你教我导致这个问题的原因应该是对齐,有没有在 Qt 中设置对齐方式,如 VC 中的“#Pragma”。
    • @wolfguolei, #pragma pack(1)
    • @wolfguolei,也可以使用#pragma pack(push) 和#pragma pack(pop) 来保存和恢复默认对齐设置。
    猜你喜欢
    • 2015-01-31
    • 2021-03-13
    • 2018-04-19
    • 2015-04-15
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多