嵌入式开发过程中结构体字节对齐问题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()即可。
總結
以上是生活随笔為你收集整理的嵌入式开发过程中结构体字节对齐问题pragma pack(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chrome安装silverlight之
- 下一篇: USB大全