• 跨平台传输结构体的注意事项


    1、什么是跨平台

    (1)这里的平台是按照CPU的位数来划分,分为32位CPU和64位CPU,不同位数CPU的差异会影响到结构体的解析;
    (2)在实际嵌入式开发中,存在"主芯片+从芯片"的多CPU的产品,或者数据需要在不同位数CPU的机器上传输;
    (3)一般传输的数据包都会封装成结构体,如果结构体在跨平台上传输就需要消除CPU位数带来的影响,保证数据接收双方对结构体的解析都正确;

    2、容易造成错误的原因分析

    (1)要消除间隙,避免CPU字长不一样,造成错位:在32位CPU中默认是4字节对齐,64位CPU中默认是8字节对齐,结构体的对齐字节数不相同会导致填充的字节数不相同,也就会造成解析结构体时变量地址错位的现象;
    (2)某些数据类型在32位CPU和64位CPU中占用的字节数不相同;

    3、结构体成员错位的情况

    3.1、示例代码

    图片:1

    (1)由于默认结构体对齐字节数的不同,导致填充字节数不一样,上面的结构体在32位CPU中占12字节,在64位CPU中占16字节;
    (2)如果通信双方是32位CPU和64CPU,各自按照自己的结构体对齐数进行发送、解析结构体,必然会因为结构体内变量地址的错位而导致不能解析出正确的数据;

    3.2、解决方法

    (1)没有什么特别好的办法,自己定义结构体时注意结构体对齐可能带来的填充字节的问题,比如不要用char类型这种大概率会需要填充的数据类型;
    (2)定义检查结构体大小的编译宏,可以在编译阶段帮你检查结构体大小是否符合预期,参考博客:《利用宏定义在编译阶段检查结构体大小的方法》

    4、数据类型大小不一致的情况

    4.1、示例代码

    图片2:

    (1)上面结构体中存在的问题,不仅存在因为对齐字节数导致的地址错位问题,还有存在变量类型在不同CPU中所在字节数不同的问题;
    (2)指针变量在32位CPU中占4字节,在64位CPU中占8字节;

    4.2、解决方法

    C类型32位机器(字节)64位机器(字节)
    char11
    short22
    int44
    long int48
    long long88
    void*(指针变量)48
    float44
    double88
    char11
    typedef struct
    {
    	char a;
    	unsigned long long ptr; //指针变量
    }testType;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (1)解决办法就是不要用在不同位数CPU中有歧义的变量类型,全部用不会有歧义的变量类型去替换;
    (2)比如:上面的指针变量"void *“类型用"unsigned long long"类型替换,这样确保无论在32位还是64位的CPU上都是占8字节,然后不同的CPU在使用变量时进行强制类型转换成"void *”;

  • 相关阅读:
    基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)
    Oracle 21版Database In-Memory LivaLabs实验(上)
    MLOps:模型监控
    【LeetCode】【Java】 最小公倍数为 K 的子数组数目
    pandas的使用
    Kubernetes leader election 源码分析
    Linux 安装 cuda
    程序员周刊(第4期):程序员的财富观
    微服务保护
    如何实现智能场景的搭建与升级?看看这家企业是怎么做的
  • 原文地址:https://blog.csdn.net/weixin_42031299/article/details/126789851