打印

预处理实现自动判断长度?

[复制链接]
2000|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
457878|  楼主 | 2019-12-20 11:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 457878 于 2019-12-20 13:51 编辑

rensas的16位mcu,结构体会16位对齐,所以带来个结构体长度判断的麻烦(copy到目标数组后的长度有可能-1),能不能用预处理搞定呢?


#define DEF_STRUCT_LEN(structName,structLen)                        \
{                                                                                                                \
        #if ((sizeof(structName)%2) == 0)                                        \
                #define structLen         ((sizeof(structName)-0)*2)        \
        #else                                                                                                \
                #define structLen         ((sizeof(structName)-1)*2)        \
        #endif                                                                                                \
}
typedef struct
{        UINT16         type;
        UINT16         len;
        char         val[14];
        // char        dumy;
}T_TLV_NBVer;

DEF_STRUCT_LEN(T_TLV_NBVer,LEN_TLV_NBVER)




使用特权

评论回复

相关帖子

沙发
dirtwillfly| | 2019-12-20 13:15 | 只看该作者
直接写个函数就好啊,然后动态申请结构体的空间就可以。不懂楼主为什么想着用预处理

使用特权

评论回复
评论
@若水 2019-12-21 20:34 回复TA
单片机也动态申请啊? 
板凳
457878|  楼主 | 2019-12-20 13:39 | 只看该作者
本帖最后由 457878 于 2019-12-20 13:46 编辑
dirtwillfly 发表于 2019-12-20 13:15
直接写个函数就好啊,然后动态申请结构体的空间就可以。不懂楼主为什么想着用预处理 ...

好多结构体,好多种数据结构,不然搞这个干嘛...
上传Keil 环境测试文件(编译失败),方便调试

testPreBuild.rar

12.37 KB

使用特权

评论回复
地板
dirtwillfly| | 2019-12-20 13:51 | 只看该作者
457878 发表于 2019-12-20 13:39
好多结构体,好多种数据结构,不然搞这个干嘛...
上传Keil 环境测试文件(编译失败),方便调试

我弄104规约,也是好多结构体和数据结构,用的动态申请内存空间和释放。不过处理器我用的stm32,现在运行没啥问题。

使用特权

评论回复
5
dirtwillfly| | 2019-12-20 13:53 | 只看该作者

使用特权

评论回复
6
457878|  楼主 | 2019-12-20 14:08 | 只看该作者
dirtwillfly 发表于 2019-12-20 13:51
我弄104规约,也是好多结构体和数据结构,用的动态申请内存空间和释放。不过处理器我用的stm32,现在运行 ...

大神...玩104规约...
个人认为,动态分配内存非常危险...

使用特权

评论回复
7
457878|  楼主 | 2019-12-20 14:27 | 只看该作者
另外,你这个动态分配,修改方便程度也不不好,来看看我怎么写的:


使用特权

评论回复
8
dirtwillfly| | 2019-12-20 15:01 | 只看该作者
457878 发表于 2019-12-20 14:08
大神...玩104规约...
个人认为,动态分配内存非常危险...

还好吧,只要注意按需要申请和释放内存,没有多大问题的

使用特权

评论回复
评论
dirtwillfly 2019-12-22 12:03 回复TA
@@若水 :如果稳定不下来,就需要自己写相应的内存碎片管理方法了。 
dirtwillfly 2019-12-22 11:57 回复TA
@@若水 :还好,我的应用经过测试,使用的最大堆空间会稳定下来。 
@若水 2019-12-21 20:35 回复TA
内存碎片怎么处理? 
9
叶春勇| | 2019-12-20 15:47 | 只看该作者
GCC 有字节对齐的特殊指令。
  struct stu{
   char sex;
   int length;
   char name[10];
  }__attribute__ ((aligned (1)));
__attribute__ ((aligned (1))); 这个就是搞对齐的。我记得以前x86也是可以字节对齐的。
你查查瑞萨的c编译手册,看看有没有。

使用特权

评论回复
10
叶春勇| | 2019-12-20 15:58 | 只看该作者

看了下手册,好像瑞萨也有这个指令。

使用特权

评论回复
11
叶春勇| | 2019-12-20 16:11 | 只看该作者

手册上举的例子

使用特权

评论回复
12
457878|  楼主 | 2019-12-20 16:20 | 只看该作者
本帖最后由 457878 于 2019-12-20 16:35 编辑
叶春勇 发表于 2019-12-20 15:58
看了下手册,好像瑞萨也有这个指令。

哪里下载的,共享一个呗,瑞萨资料不好找,特别是中文资料
实际情况是:地址会跳跃如图,然后用sizeof取到的全部是双数...

使用特权

评论回复
13
叶春勇| | 2019-12-20 16:37 | 只看该作者
我在网上胡乱搜的。希望对你有用。

瑞萨编译器手册.pdf

3.4 MB

使用特权

评论回复
14
叶春勇| | 2019-12-20 16:49 | 只看该作者
本帖最后由 叶春勇 于 2019-12-20 16:55 编辑
457878 发表于 2019-12-20 16:20
哪里下载的,共享一个呗,瑞萨资料不好找,特别是中文资料
实际情况是:地址会跳跃如图,然后用sizeof取到 ...

你这个好像是结构体中含有结构体。是不是每个结构定义都要用。
你这个涉及到,结构体内成员的对齐,还有结构体与结构体之间的对齐。

使用特权

评论回复
15
457878|  楼主 | 2019-12-20 17:15 | 只看该作者
本帖最后由 457878 于 2019-12-20 17:17 编辑
叶春勇 发表于 2019-12-20 16:49
你这个好像是结构体中含有结构体。是不是每个结构定义都要用。
你这个涉及到,结构体内成员的对齐,还有结 ...

结构体内也是乱套的,这个是最顶层结构体:



使用特权

评论回复
16
叶春勇| | 2019-12-20 20:00 | 只看该作者
457878 发表于 2019-12-20 17:15
结构体内也是乱套的,这个是最顶层结构体:

编译指令,用了吗。贴出来看看

使用特权

评论回复
17
457878|  楼主 | 2019-12-21 13:27 | 只看该作者
本帖最后由 457878 于 2019-12-21 13:29 编辑
叶春勇 发表于 2019-12-20 20:00
编译指令,用了吗。贴出来看看
没用编译指令:

test.rar (39.94 KB)


使用特权

评论回复
18
叶春勇| | 2019-12-21 13:47 | 只看该作者
457878 发表于 2019-12-21 13:27
没用编译指令:

state2 x10ms调换位置呢?

使用特权

评论回复
19
457878|  楼主 | 2019-12-21 15:22 | 只看该作者
本帖最后由 457878 于 2019-12-21 15:33 编辑
叶春勇 发表于 2019-12-21 13:47
state2 x10ms调换位置呢?

实际应用中state2是没有的...搞上去是强调这个乱套 :)
暂行方案:
1.用“目测”的方法,手动定义长度,
2.然后在转换的时候使用手动定义的长度



使用特权

评论回复
20
叶春勇| | 2019-12-21 16:30 | 只看该作者
457878 发表于 2019-12-21 15:22
实际应用中state2是没有的...搞上去是强调这个乱套 :)
暂行方案:
1.用“目测”的方法,手动定义长度,
#include<stdio.h>
#include<stdint.h>

#pragma pack (1)
typedef struct
{
        uint16_t x10ms;
        uint8_t state;        //2 bytes used
}stru1_typedef;

typedef struct
{
        uint8_t state;
        uint16_t x10ms;
        uint8_t state2;        //2 bytes used
} stru2_typedef ;

typedef struct
{
        uint16_t x10ms;
        uint8_t state;
        uint8_t state2;        //2 bytes used
} stru3_typedef ;

stru1_typedef a[10];
stru2_typedef b[10];
stru3_typedef c[10];

int main(void)
{
        uint8_t *p;
        printf("%d,%d\n",(uint8_t*)&a[1]-(uint8_t*)&a[0],sizeof(stru1_typedef));
        printf("%d,%d\n",(uint8_t*)&b[1]-(uint8_t*)&b[0],sizeof(stru2_typedef));
        printf("%d,%d\n",(uint8_t*)&c[1]-(uint8_t*)&c[0],sizeof(stru3_typedef));
        a[0].state=0xa5;
        b[0].state2=0xa5;
        c[0].state=0xa5;
       
        p=(uint8_t *)&a[0];
        printf("%d\n",p[2]);
        p=(uint8_t *)&b[0];
        printf("%d\n",p[3]);
        p=(uint8_t *)&c[0];
        printf("%d\n",p[2]);
       
}

编译指令有用的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:不正常人类

270

主题

885

帖子

3

粉丝