- 🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用
- 🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】
- 🍅 玩转CANoe,博客目录大全,点击跳转👉
目录
- CAPL为什么也要理解字节对齐呢?
- CAPL 字节对齐脚本实例
- 🌎总结
CAPL为什么也要理解字节对齐呢?
一般情况下,我们在定义/使用结构体的情况下,不需要考虑字节对齐的问题,因为CAPL运行在WIndows系统上,我们也不差那点内存消耗,但是如果你想更进一步的运用结构体,比如下面的CAPL函数结构体和数组想换转换时就要考虑到结构体字节对齐的问题了,不然有可能得不到期望的结果
CAPL 字节对齐脚本实例
计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,为了内存读写效率,计算机并非逐字节大小读写内存,而是以2,4,或8的倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。
CAPL 基于C语言,但是CAPL有自己的字节对齐规则,且CAPL封装了自己的函数来读取字节对齐和设置字节对齐,下图是结构体字节对齐的相关函数
先看一个简单的示例,结构元元素是相同的元素,结构体大小就是所有元素的字节大小之和。
on key 'b'
{
struct Point
{
byte x; // offset 0, size 1
byte y; // alignment 1, offset 1, size 1, padding before: 0
}; // size 2, alignment (of the struct) 1
write("结构体占内存字节数:%d",__size_of(struct Point));
write("结构体的字节对齐:%d",__alignment_of(struct Point));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct Point,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct Point,y));
}
输出结果
Program / Model 结构体占内存字节数:2
Program / Model 结构体的字节对齐:1
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:1
- 结构体元素不是相同类型时:
- 字节对齐大小是结构体中元素最大的那个元素,如果最大成员的类型是qword(8字节),则该结构体的字节对齐大小就是8字节
- 如果结构体的后一个成员比前一个成员大,则后一个成员的内存地址偏移量 = 前一个内存地址偏移量 + 后一个成员的字节大小 。比如qword前面是byte ,则 qword的内存偏移量是就是(0+8)
- 如果结构体的后一个成员比前一个小,则后一个成员的内存地址偏移量 = 前一个内存地址偏移量 + 前一个成员字节大小 。 比如byte z比 qword y 小,则 byte z的偏移量(16)= 8+8
- 结构体占内存大小(20) = 最后一个元素的偏移量(18) + 它的大小(2)
on key 'b'
{
struct LongPoint
{
byte x; // offset 0, size 1
qword y; // alignment 8, offset 8, size 8, padding before: 7
byte z; // alignment 1, offset 16, size 1, padding before: 0
int k; // alignment 2, offset 18, size 2, padding before: 1
}; // size 20, alignment (of the struct) 8
write("结构体占内存字节数:%d",__size_of(struct LongPoint));
write("结构体的字节对齐:%d",__alignment_of(struct LongPoint));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct LongPoint,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct LongPoint,y));
write("结构体的元素z内存地址偏移量:%d",__offset_of(struct LongPoint,z));
write("结构体的元素k内存地址偏移量:%d",__offset_of(struct LongPoint,k));
}
输出结果
Program / Model 结构体占内存字节数:20
Program / Model 结构体的字节对齐:8
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:8
Program / Model 结构体的元素y内存地址偏移量:16
Program / Model 结构体的元素y内存地址偏移量:18
CAPL字节对齐的原则:字节对齐数字只有1, 2, 4, 8可以用,如果没有指定,则默认字节对齐大小为结构体元素中最大元素的字节大小。可以通过_align() 函数来指定对齐大小
下面代码通过设置_align(1) ,_align(2) ,_align(4) 来对比下结果。
on key 'b'
{
{
struct LongPoint
{
byte x;
qword y;
byte z;
int k;
};
write("*********************默认对齐大小********************************");
write("结构体占内存字节数:%d",__size_of(struct LongPoint));
write("结构体的字节对齐:%d",__alignment_of(struct LongPoint));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct LongPoint,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct LongPoint,y));
write("结构体的元素z内存地址偏移量:%d",__offset_of(struct LongPoint,z));
write("结构体的元素k内存地址偏移量:%d",__offset_of(struct LongPoint,k));
}
{
_align(1) struct LongPoint
{
byte x;
qword y;
byte z;
int k;
};
write("*********************_align(1) ********************************");
write("结构体占内存字节数:%d",__size_of(struct LongPoint));
write("结构体的字节对齐:%d",__alignment_of(struct LongPoint));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct LongPoint,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct LongPoint,y));
write("结构体的元素z内存地址偏移量:%d",__offset_of(struct LongPoint,z));
write("结构体的元素k内存地址偏移量:%d",__offset_of(struct LongPoint,k));
}
{
_align(2) struct LongPoint
{
byte x;
qword y;
byte z;
int k;
};
write("*********************_align(2) ********************************");
write("结构体占内存字节数:%d",__size_of(struct LongPoint));
write("结构体的字节对齐:%d",__alignment_of(struct LongPoint));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct LongPoint,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct LongPoint,y));
write("结构体的元素z内存地址偏移量:%d",__offset_of(struct LongPoint,z));
write("结构体的元素k内存地址偏移量:%d",__offset_of(struct LongPoint,k));
}
{
_align(4) struct LongPoint
{
byte x;
qword y;
byte z;
int k;
};
write("*********************_align(4) ********************************");
write("结构体占内存字节数:%d",__size_of(struct LongPoint));
write("结构体的字节对齐:%d",__alignment_of(struct LongPoint));
write("结构体的元素x内存地址偏移量:%d",__offset_of(struct LongPoint,x));
write("结构体的元素y内存地址偏移量:%d",__offset_of(struct LongPoint,y));
write("结构体的元素z内存地址偏移量:%d",__offset_of(struct LongPoint,z));
write("结构体的元素k内存地址偏移量:%d",__offset_of(struct LongPoint,k));
}
}
输出结果:
Program / Model 默认对齐大小***********
Program / Model 结构体占内存字节数:20
Program / Model 结构体的字节对齐:8
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:8
Program / Model 结构体的元素z内存地址偏移量:16
Program / Model 结构体的元素k内存地址偏移量:18
Program / Model *********************_align(1) ********************************
Program / Model 结构体占内存字节数:12
Program / Model 结构体的字节对齐:1
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:1
Program / Model 结构体的元素z内存地址偏移量:9
Program / Model 结构体的元素k内存地址偏移量:10
Program / Model *********************_align(2) ********************************
Program / Model 结构体占内存字节数:14
Program / Model 结构体的字节对齐:2
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:2
Program / Model 结构体的元素z内存地址偏移量:10
Program / Model 结构体的元素k内存地址偏移量:12
Program / Model *********************_align(4) ********************************
Program / Model 结构体占内存字节数:16
Program / Model 结构体的字节对齐:4
Program / Model 结构体的元素x内存地址偏移量:0
Program / Model 结构体的元素y内存地址偏移量:4
Program / Model 结构体的元素z内存地址偏移量:12
Program / Model 结构体的元素k内存地址偏移量:14
🌎总结
- 🚩要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!
- 🚩如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。