嵌入式开发过程中结构体字节对齐问题pragma pack(1)

一、引言

曾经刚入门嵌入式在开发一个应用时,用到了自定义结构体,底层嵌入式单片机运行该结构体没问题,但是在Qt开发应用软件对接协议时,一直通不过,仔细分析才发现是QT这边的结构体字节并没有按照单字节对齐,后来在定义结构体时,增加了宏定义,强迫该结构体按照单字节对齐的方式进行编译,即可解决问题。

二、问题描述

假设有一个结构体,包含5字节头,一个字长度的负载,和一个字节的尾,例如:

typedef struct
{char head[5];unsigned short value;char endFlag;
}CMD_TypeDef;CMD_TypeDef TCMD;

很明显,这个结构体的字节大小为5+2+1=8字节,但是用sizeof对各个域进行测试,发现总共的字节数并不是8,测试代码如下:

qDebug()<<"size"<<QString::number(sizeof(TCMD.head));  
qDebug()<<"size"<<QString::number(sizeof(TCMD.value));
qDebug()<<"size"<<QString::number(sizeof(TCMD.endFlag));
qDebug()<<"size"<<QString::number(sizeof(TCMD));

打印结果为:

size "5"
size "2"
size "1"
size "10"

进一步地,对这个结构体进行赋值,用并串口发出去该结构体的具体数据:

TCMD={{'A','T','+','D','='},10,0x0A};
port->write(( char*) &TCMD,sizeof(TCMD));

串口收到的数据为:41 54 2B 44 3D 1A 0A 00 0A 00

明显看到数据多了1A  和 00.

三、问题分析

从上面的串口收到结果来看,TCMD第一个成员head 变成了6字节【41 54 2B 44 3D 1A】,TCMD的成员endflag变成了2字节【0A 00】,结构体TCMD成员占用的内存分别是 6+2+2=10字节。

QT中定义的结构体在对成员进行内存分配时,往往按照“N”字节对齐的方式,即所有内容按照N字节的方式进行占用内存,如果剩余的内容占不满N字节,则N字节剩下的字节仍然给该结构成员,新的成员重新从下一个N字节进行对齐。

以上面的例子来说,显然N=2,即机构体按照2字节进行对齐,TCMD的头部head占5字节,需要占用3个N=6字节,负载value等于2字节,刚好占用一个N,而尾部endflag占用1字节,不足N,仍然需要占用一个N。

四、解决方法

既然QT编译系统对结构体按照N字节对齐,那么能否根据需要指定对齐的N数呢,其实C语言提供了这种操作,采用宏定义:

#pragram pack(N)
......//结构体定义内容
#pragram pack()

即可指定该定义的结构体内存对齐方式。

具体地,上述问题可以这样解决:

#pragram pack(1)
typedef struct
{char head[5];unsigned short value;char endFlag;
}CMD_TypeDef;
#pragram pack()CMD_TypeDef TCMD;

结构体定义的时候加上:#pragma pack(1)

定义结束部分结尾 #pragma pack()即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Exchange2003-2010迁移系列之二,迁移前的准备工作(上)

Exchange2010迁移前的准备工作&#xff08;上&#xff09; 上篇博文发出后&#xff0c;很多博友支持得非常给力&#xff0c;在此一并谢过&#xff01;也有一些博友反映看得不是很明白&#xff0c;但仍然支持…..本文中首先就环境问题再为大家解释一下&#xff0c;然后介绍如何进…

BMP图像文件格式分析附带图解

From: http://www.raidcn.com/js/BMPTuXiangWenJianGeShiFenXiFuDaiTuJie.html 认识BMP文件格式&#xff0c;以及bmp文件存储结构 &#xff0c;通过winhex查看文件结构解析。 一、认识BMP文件格式. 1、 BMP格式是由微软公司开发。通常BMP图像文件的后缀名是BMP&#xff0c;但…

matlab安装MinGW-64代码C/C++编译器的方法

一、说明 matlab中编写的m文件转成C/C代码&#xff0c;以及matlab中执行C/C带啊&#xff0c;需要用到mex 查看matlab是否支持可以输入mex -setup&#xff1a; 二、安装 如果不支持&#xff0c;没找到&#xff0c;则需要重新安装&#xff0c;下载地址&#xff1a;http://tdm-…

mybatis+spring+c3p0+maven+ehcache

项目截图 pom.xml如下 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">…

windbg linux内核调试,windbg调试虚拟机XP系统

一、先介绍一下被调试的虚拟机系统环境:虚拟机:vmware workstation 10.0版本虚拟机操作系统: Microsoft windows xp professional 2002 service pack3cpu:2.8GHz,2.64GB内存二、这个没有直接关系。做个笔记而已。1.在XP系统中&#xff0c;创建了一个first.c文件测试代码如下:#i…

VC屏幕截图,保存为Bmp文件

新建一个MFC基于对话框的应用程序&#xff0c;在界面上放一个Button&#xff0c;为其实现点击事件&#xff0c;代码如下&#xff1a; void CScreenShotDlg::OnBtnScreenshot() {RECT rect {0, 0, 1900, 1000};HBITMAP hbmp CopyScreenToBitmap(&rect);SaveBitmapToFile(h…

C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...

做软件&#xff0c;有点儿类似铁人三项比赛&#xff1f;赛跑、射击、游泳? 光某个环节突出&#xff0c;也没多大用&#xff0c;需要整体能力都强&#xff0c;能把整体都可以搞定&#xff0c;才容易得到比赛的胜利&#xff0c;光某一环节非常优秀&#xff0c;也赢得不来整个比…

C语言中的格式化打印printf/sprintf以及嵌入式printf重定向进行DEBUG

一、printf描述 在C语言中&#xff0c;打印函数主要包括printf/sprintf/fprintf/snprintf等等&#xff0c;目的是将“给定的内容”按照“指定的格式”输出到“指定目标内”。通常要使用时&#xff0c;需要包括#inlcude <stdio.h>头文件。 用法为&#xff1a;void print…

华为网卡支持linux,在openwrt下对华为WA633无线AP的千兆网卡驱动进行支持

1.下面是这款AP的全裸图&#xff0c;AP的无线网卡采用了AR9223&#xff0c;PHY采用了博通的BCM5461&#xff0c;主控CPU位octeon 500&#xff0c;射频功放采用的是RF5602方案。由于这款CPU并不常见&#xff0c;我至今未在网上找到它的datasheet&#xff0c;导致我们在玩这款AP的…

hdu120118岁生日

Problem DescriptionGardon的18岁生日就要到了&#xff0c;他当然很开心&#xff0c;可是他突然想到一个问题&#xff0c;是不是每个人从出生开始&#xff0c;到达18岁生日时所经过的天数都是一样的呢&#xff1f;似乎并不全都是这样&#xff0c;所以他想请你帮忙计算一下他和他…

React开发(223):详情页根据数组map处理返回值

<Col span{6}>{isDicTonList &&isDicTonList.map((item, index) > {if (item.key afterDetail.status) {return item.value;}})}</Col>

Linux下C语言实现LCD屏幕截图

From: http://blog.chinaunix.net/uid-24789420-id-3191806.html 一、概述 最近看到网上有人问怎么用C语言实现屏幕截图&#xff0c;刚好自己也在研究Linux驱动&#xff0c;于是花了半天时间把Linux的FrameBuffer驱动看懂了个七八&#xff0c;接着就动手写了个LCD屏幕截图的应…

C语言中#、##宏定义的用法

一、#的用法 #用于编译器编译过程进行预处理。 1、宏定义 #define ON 1#ifndef _PARA_ #define _PARA_ #enddef#ifdef _PARB_ #define DEFAULT_SIZE 1024 #enddef2、宏开关 #if VAR ... #elif ... #end3、显示设定错误 #error ERROR: Not Define4、设置字节对齐 #pragma pac…

linux 正则表达式 视频教程,30分钟带你玩转正则表达式

定义&#xff1a;正则表达式说白了就是有普通字符、以及特殊字符组成的文子模式。{匹配模式标准}正则表达式将会作为一个模板与所搜索的字符串进行匹配。可以让使用者轻易达到搜寻/删除/取代某些特定字符的处理程序。此外vim、grep、find、awk、sed等命令都支持正则表达式注&am…

React开发(224):ant design label绑定值

<Col span{12}><Form className{form-customer} label"同意退运费"><span style{{ fontSize: 14 }}>&#xffe5;</span><Form.Item style{{ width: 20% }}>{getFieldDecorator(freight)(<InputNumber step{1} precision{2} min{0…

数据采集工具flume

概述 flume是在2011年被首次引入到Cloudera的CDH3分发中&#xff0c;2011年6月&#xff0c;Cloudera将flume项目捐献给Apache基金会。2012年&#xff0c;flume项目从孵化器变成了顶级项目&#xff0c;在孵化的这一年中&#xff0c;开发人员就已经开始基于Star Trek Themed标签对…

电脑SSH登陆树莓派Raspberry的两种方式

采用SSH登陆Raspberry需要提前知道Raspberry的IP&#xff0c;SSH登陆端口为22&#xff0c;这里分享两种基于SSH网络登陆树莓派的方式。 一、利用路由器搭建局域网登陆树莓派 1、用路由器搭建局域网&#xff0c;电脑无线或有线方式连接路由器&#xff0c;树莓派用网线连接路由…

linux命令修改内容怎么回退,linux命令(修改).doc

linux命令(修改)第一组 用户管理类命令1 添加用户useradd [选项] 用户名范例&#xff1a;useradd davidls /home vim /etc/passwd2 修改密码passwd [选项] 用户名范例&#xff1a;useradd davidls /home passwd david(修改密码)3 删除用户userdel [选项] 用户名范例&#xff1a…

使用数据库的压测工具super-smack测试mysql数据库性能

一、下载super-smack下载地址&#xff1a;http://vegan.net/tony/supersmack/源码&#xff1a;http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz二、编译及安装配置编译选项&#xff1a;./configure --prefix/usr/local/super-smack-1.3 --with-mysql --with-smacks-d…

React开发(225):render中返回的值可以定义为一个方法

/*** 商品信息 图片&#xff0c;名称、code展示* param {*} data*/goodInfoVal (data) > {return (<div style{{ display: flex, alignItems: center }}><img style{{ width: 100px, marginRight: 8px }} src{data.productImg} alt"" /><div>&…