IAR中使用struct强制对齐时的一个问题及解决
2014-02-14 15:46
1896 查看
最近在用IAR开发MSP430程序过程中发现了一个问题,具体描述是这样的
首先定义了一个struct并强制1个字节对齐
然后写了一个函数
在调用的时候将结构体中4字节的数据取地址并当参数传入
StrToNum(p,',',&(rxlbs.longitude))
不仅会报告一个警告Warning[Pa039]: use of address of unaligned structure member
运算出来的数据有时也会不对
最后经我调试发现,当&(rxlbs.longitude)的地址是奇数的时候,对其对应参数*num的直接赋值操作会运算到其地址的前一个字节地址,导致结构成员nshemi的值变掉,而运算出来的longitude值也不对,因此,在430中存储结构正常是以偶数地址开始,而人为的定义struct并强制1个字节对齐会导致其成员会出现奇地址的出现,而用奇地址的成员取地址并传参数给函数,函数内部对其的赋值会出错。
解决办法
1,不使用1字节对齐方式
2,如果非要使用,不要对没对齐的struct成员取地址,可以直接赋值
3,非要有上述操作,不能使用将取地址后当参数传入的成员指针直接赋值运算等方式,可以临时建一个变量操作,操作完后将变量的值memcpy到成员的指针。
比如将我上述的函数改成
首先定义了一个struct并强制1个字节对齐
#pragma pack(push) //保存对齐状态 #pragma pack(1)//设定为4字节对齐 typedef struct { uint8_t fix_mode; uint32_t latitude; //纬度 分扩大100000倍,实际要除以100000 uint8_t nshemi; //北纬/南纬,N:北纬;S:南纬 uint32_t longitude; //经度 分扩大100000倍,实际要除以100000 uint8_t ewhemi; //东经/西经,E:东经;W:西经 }GprsLBS; #pragma pack(pop) //保存对齐状态
然后写了一个函数
u_char StrToNum(u_char *str,char end_char,u_int *num) { uint8_t i = 0; while(str[i] != end_char) { if(str[i] <= '9' && str[i] >= '0') { (*num) = (*num)*10 + (str[i] - 0x30); } else if(str[i] == '.') { } else { return 0; } i ++; } return 1; }
在调用的时候将结构体中4字节的数据取地址并当参数传入
StrToNum(p,',',&(rxlbs.longitude))
不仅会报告一个警告Warning[Pa039]: use of address of unaligned structure member
运算出来的数据有时也会不对
最后经我调试发现,当&(rxlbs.longitude)的地址是奇数的时候,对其对应参数*num的直接赋值操作会运算到其地址的前一个字节地址,导致结构成员nshemi的值变掉,而运算出来的longitude值也不对,因此,在430中存储结构正常是以偶数地址开始,而人为的定义struct并强制1个字节对齐会导致其成员会出现奇地址的出现,而用奇地址的成员取地址并传参数给函数,函数内部对其的赋值会出错。
解决办法
1,不使用1字节对齐方式
2,如果非要使用,不要对没对齐的struct成员取地址,可以直接赋值
3,非要有上述操作,不能使用将取地址后当参数传入的成员指针直接赋值运算等方式,可以临时建一个变量操作,操作完后将变量的值memcpy到成员的指针。
比如将我上述的函数改成
u_char StrToNum(u_char *str,char end_char,u_int *num) { uint8_t i = 0; uint32_t num_temp = 0; while(str[i] != end_char) { if(str[i] <= '9' && str[i] >= '0') { num_temp = num_temp*10 + (str[i] - 0x30); } else if(str[i] == '.') { } else { return 0; } i ++; } memcpy(num,&num_temp,sizeof(u_int)); return 1; }
相关文章推荐
- 在使用BizTalk时遇到一个很郁闷的问题 之解决篇
- 使用PLSQL Developer时,“ORA-12154: TNS:无法解析指定的连接标识符”问题的一个解决办法
- 在使用Hibernate时,因为一个查询需要更多的表连接而要使用SQL来解决性能问题。然而返回的结果集中包含了没有映射的Entity类中的表字段,在这个SQL中还有使用如何将层次关系的父子结点显示为横行
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三).so文件编译过程问题的解决
- ASP“操作必须使用一个可更新的查询”问题的解决办法
- 这是我学习COM遇到的几个基本问题其解决 黄森堂(vcmfc)著 1.我用ATL生成一个组件对象,我在COM中使用IDD_IEncrypt,这个在哪里写义,是啥?GUID? 答:IDD_IEncry
- 在Intellij idea里使用Maven构建一个webapp骨架项目解决一直downloading问题
- 关于ASP.NET“操作必须使用一个可更新的查询”问题的解决方法
- 使用eclipse进行Android编程发生崩溃的一个问题及解决办法
- 如何使用Maven的archetype快速生成一个新项目(解决生成项目目录不完整问题)
- phonegap - 解决ios中使用定位的页面会跳出一个用户确认提示的问题
- 使用PLSQL Developer时,“ORA-12154: TNS:无法解析指定的连接标识符”问题的一个解决办法
- win7问题解决,凭据管理器和无法访问,不允许一个用户使用一个以上用户名与服务器或共享资源进行多重连接。
- Spring @Async配置4. 基于@Async无返回值调用 使用的方式非常简单,一个标注即可解决所有的问题: 1 @Async //标注使用 2 public void asyncMe
- 使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
- 如何解决ADO.NET访问Access数据库出现"操作必须使用一个可更新的查询"的问题(非原创,摘自书中)
- html中textarea的使用及常见的一个问题解决
- 解决网站使用sqlite时并发问题的一个经验
- 新买的stm8使用IAR烧录出错问题解决
- 使用docker 解决一个小问题,你也可能用的到