搜索
bottom↓
回复: 15

联合体中的结构体与数组如何相对应?

[复制链接]

出590入992汤圆

发表于 2018-1-22 11:49:59 | 显示全部楼层 |阅读模式
本帖最后由 SUPER_CRJ 于 2018-1-22 11:51 编辑

关于字节对齐问题:使用联合体如下,本质是希望:第二个结构体中的数据正好按照顺序和上面的Buf相对应(比如第一个结构体中Buf[0]对应toUploadHeard0、Buf[39]对应:toUploaderTail]),这样的话,在批量发送的时候可以用数组来,操作实际数据的时候用变量名来,但是实际中发现:第二个结构体,因为对齐问题,实际上在fileNumbers时候已经不和Buf[3]Buf[4]Buf[5]对应了,但是使用:__attribute__ ((aligned (1))); 在联合体后面,第一个结构体后面和第二个结构体后面,仍然还是不能对应。这样应该如何操作?
typedef union
{
        struct
        {
                u8 Buf[40];
        };
        struct
        {
                u8 toUploadHeard0; // 0xAA
                u8 toUploadHeard1; // 0x55
                u8 functionCode;   // 0x01
                u16 fileNumbers;
                u32 RemainingSize;
                u32 RemainingContinuousMaxSize;
                u8 radomCode[8];
                u16 bootloaderVersion;
                u16 APPVersion;
                u16 HardWareVersion;
                u8 Res[11];
                u8 sum;
                u8 toUploaderTail; // 文件尾巴
        };
}_UpStatusInfo ;

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入22汤圆

发表于 2018-1-22 11:50:00 | 显示全部楼层
要加 PACK关键字

出0入0汤圆

发表于 2018-1-22 16:37:14 | 显示全部楼层
用的啥单片机?51?STM32?

出0入0汤圆

发表于 2018-1-22 16:42:13 | 显示全部楼层
如果51的话,用#pragma pack(1)可以解决
STM32的话,这样会大幅影响效率,不推荐

出0入0汤圆

发表于 2018-1-22 16:47:57 | 显示全部楼层
目测    这段代码编译不过去吧   不知道你用的什么编译器

出0入0汤圆

发表于 2018-1-22 16:54:48 | 显示全部楼层
本帖最后由 unnormal 于 2018-1-22 16:56 编辑

u8 toUploadHeard0; // 0xAA
u8 toUploadHeard1; // 0x55
u8 functionCode;   // 0x01
u8 sum;      
u32 RemainingSize;
u32 RemainingContinuousMaxSize;
u8 radomCode[8];
u16 bootloaderVersion;
u16 APPVersion;
u16 HardWareVersion;
u16 fileNumbers;
u8 Res[11];               
u8 toUploaderTail;

虽然不能解决根本问题  但是可以隔靴搔痒

出0入0汤圆

发表于 2018-1-22 17:03:17 | 显示全部楼层
这其实是结构体问题,默认情况,成员偏移地址是成员字节数的整数倍,其余留空

出0入0汤圆

发表于 2018-1-23 23:26:40 来自手机 | 显示全部楼层
强制对齐影响效率  习惯人为填充对齐

出0入0汤圆

发表于 2018-1-23 23:27:30 来自手机 | 显示全部楼层
隐性自动对齐不直观别扭

出10入61汤圆

发表于 2018-1-24 07:28:38 | 显示全部楼层
发送不需要数组,直接取结构体地址转换成char指针一样的

出0入0汤圆

发表于 2018-1-24 08:27:51 | 显示全部楼层
#pragma pack(push)  /* 保存原来的对齐方式 */
#pragma pack(1)  /* 使用单字节对齐 */

typedef union _xxxx
{
  yyyy;
}xxxx;
#pragma pack(pop)  /* 恢复原来的对齐方式 */

出0入0汤圆

发表于 2018-1-24 13:10:04 | 显示全部楼层
题外话,一般这种情况都是用强制类型装换,把机构体指针转换为数组指针然后使用

出0入0汤圆

发表于 2018-1-24 13:31:37 | 显示全部楼层
建议如下使用填充对其,不要强制使用PACK对其,效率影响极其明显(尤其是在低速单片机上):
  1. typedef union {
  2.         struct {
  3.                 u8 Buf[40];
  4.         };
  5.         struct{
  6.                 u8 toUploadHeard0; // 0xAA
  7.                 u8 toUploadHeard1; // 0x55
  8.                 u8 functionCode;   // 0x01
  9.                 u8 reserve1;
  10.                 u16 fileNumbers;
  11.                 u16 reserve2;
  12.                 u32 RemainingSize;
  13.                 u32 RemainingContinuousMaxSize;
  14.                 u8 radomCode[8];
  15.                 u8 reserve3;
  16.                 u8 reserve4;
  17.                 u8 reserve5;
  18.                 u16 bootloaderVersion;
  19.                 u16 APPVersion;
  20.                 u16 HardWareVersion;
  21.                 u16 reserve6;
  22.                 u8 Res[11];
  23.                 u8 sum;
  24.                 u8 toUploaderTail; // 文件尾巴
  25.                 u8 reserve8;
  26.         };
  27. }_UpStatusInfo ;
复制代码

如果必须要保证成员的顺序,那么使用如上填充对齐较好(缺点是占用一些RAM)。如果没必要保证成员顺序,那么建议U8四个一组,u16两个一组紧邻一起。这样可以保证自动对其。
发送数据是,通过对联合体中的结构体成员赋值。发送的时候直接发送联合体中的数组,接受解析时直接再解析结构体的成员即可。

出0入0汤圆

发表于 2018-1-24 13:32:25 | 显示全部楼层
pingdan32 发表于 2018-1-24 13:31
建议如下使用填充对其,不要强制使用PACK对其,效率影响极其明显(尤其是在低速单片机上):

如果必须要保 ...

不好意思,联合体中的数组成员大小修改一下即可。上文忘记修改了。

出590入992汤圆

 楼主| 发表于 2018-1-24 16:21:23 | 显示全部楼层
pingdan32 发表于 2018-1-24 13:31
建议如下使用填充对其,不要强制使用PACK对其,效率影响极其明显(尤其是在低速单片机上):

如果必须要保 ...

好的,非常感谢,但是设计方案已经出来了,暂时就用Pack了!

出590入992汤圆

 楼主| 发表于 2018-1-24 16:22:16 | 显示全部楼层
zhugean 发表于 2018-1-22 16:42
如果51的话,用#pragma pack(1)可以解决
STM32的话,这样会大幅影响效率,不推荐 ...

收到,数据量不大,但是报文协议需要这样做。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 15:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表