c - union 无法解码字节数组

标签 c

以下代码无法解码纬度和经度。 输出为:132, 1, 1645780273, 77276230, 0, -0.000000, 0.000000,对最后两个值纬度和经度进行了错误的转换。 如果我删除前 4 个值并从结构中删除 uint32_t identifiers; 我得到正确的结果 132, 1, 1645780273, 77276230, 0, 59.877871, 10.465200

非常感谢任何有助于理解这种行为的帮助。

#include <stdio.h>
#include <string.h>
int main() {
    union  {
        unsigned char bytes[36];
        struct{
            uint32_t identifier;
            uint16_t telegram_size;
            uint16_t telegram_version;
            uint32_t seconds;
            uint32_t nanoseconds;
            uint32_t stat;
            double latitude;
            double longitude;
      }unpack;
    }telegram;

    unsigned char values[] = {0x23, 0x4B, 0x4D, 0x42, 0x84, 0x00, 0x01, 0x00, 0x31, 0x9d, 0x18, 0x62, 0x46, 0x24, 0x9b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x3e, 0x2c, 0x11, 0x5e, 0xf0, 0x4d, 0x40, 0xCA, 0x32, 0xC4, 0xB1, 0x2E, 0xEE, 0x24, 0x40};
    memcpy(telegram.bytes, values, 36);

    for (int i=0;i<36;i++){
        printf("%02X ", telegram.bytes[i]);
    }
    printf("\n%u, %u, %u, %u, %u, %f, %f\n", telegram.unpack.telegram_size, telegram.unpack.telegram_version, telegram.unpack.seconds, telegram.unpack.nanoseconds, telegram.unpack.stat, telegram.unpack.latitude, telegram.unpack.longitude);
    return 0;
}

更新:据我从下面的评论中了解到,结构如下所示: enter image description here

最佳答案

这与结构填充有关。

一般来说,结构的成员从偏移量开始,该偏移量是该成员大小的倍数,用于对齐目的。因此,statlatitude 成员之间有 4 个填充字节,因此后者可以驻留在 8 的倍数的偏移量处。这意味着结构是比你想象的大 4 个字节。

如果可以,您应该重新排列成员,使它们以自然偏移对齐,这样成员之间就没有填充(尽管最后可能仍然有填充)。

如果这不是一个选项,您可以使用特定于编译器的属性来打包结构。如果您使用 gcc,您将执行以下操作:

    struct __attribute__((__packed__)) {
        uint32_t identifier;
        uint16_t telegram_size;
        uint16_t telegram_version;
        uint32_t seconds;
        uint32_t nanoseconds;
        uint32_t stat;
        double latitude;
        double longitude;
  }unpack;

另请注意,在某些架构上,未对齐的读取或写入可能会导致崩溃。

关于c - union 无法解码字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71271541/

相关文章:

c - C 中的 UNIX 共享内存和信号量

c - 自由自在

c++ - Eclipse:C++静态库中的C代码,由C++库引用导致 undefined reference

c++ - 创建并链接到从旧 DLL 文件生成的 .lib 文件

c - 为什么在 UNIX 中只分配最低的可用文件描述符?

c - 请求非结构或 union 中的成员 'isr_status'

C 输入中的电路模拟器

c - 如何检查远程UDP端口是否打开? C

C LIBCHAMPLAIN 段错误?

c - 使用 Dwarf DebugInfo 和源代码将 Var 映射到声明