BitField 位域
1. BigEndian: 从逻辑最高bit开始分配
SmallEndian: 从逻辑最低bit开始分配
short tmp = 0xAAAA;
对tmp变量来说,
什么是逻辑最高bit: (0x1 << 15) 对应的就是逻辑最高bit
什么是逻辑最低bit: (0x1) 对应的就是逻辑最低bit
2. 举例
定义一个union
union TestUnion {
short A;
struct {
short x:7;
short y:9;
} B;
}
TestUnion u;
u.B.x = 0b0000111 == 7;
u.B.y = 0b000001001 == 9;
对SmallEndian来说,就是从逻辑最低bit开始分配
u.A == 0b000001001(y) 0b0000111(x)
== 0b0000010010000111
== 0x0487
对BigEndian来说,就是从逻辑最高bit开始分配
u.A == 0b0000111(x) 0b000001001(y)
== 0b0000111000001001
== 0x0E09
3. 网络传输中的BitField
2.中可以看出,同样的TestUnion在 BigEndian SmallEndian 上的解释是不一样的.
为了解决这个问题,需要在 BigEndian SmallEndian 上对TestUnion作不同的定义
在 SmallEndian上
union TestUnion {
short A;
struct {
short x:7;
short y:9;
} B;
}
TestUnion u;
u.B.x = 0b0000111 == 7
u.B.y = 0b000001001 == 9
u.A == 0x0487
&(u.A)[0] == 0x87
&(u.A)[1] == 0x04
通过网络传输之前,先转换为网络字节序(也就是BigEndian)
&(u.A)[0] == 0x04
&(u.A)[1] == 0x87
通过网络发送给BigEndian之后,BigEndian收到的是
&(u.A)[0] == 0x04
&(u.A)[1] == 0x87
u.A == 0x0487
== 0b0000 0100 1000 0111
如果还是按照SmallEndian上的TestUnion定义来解释, BigEndian就会从逻辑最高bit开始分配BitField
u.B.x == 0b0000010 == 2
u.B.y == 0b010000111 == 135
这就导致了TestUnion通过网络传输由SmallEndian到BigEndian之后,u.B.x 和 u.B.y的值不一致
这时只要
在 BigEndian上
union TestUnion {
short A;
struct {
short y:9; <<-- 把所有位域的成员位置逆序
short x:7;
} B;
}
把所有位域的成员位置逆序 就可以了.
于是, 按照以上的BigEndian上TestUnion定义来解释, BigEndian就会从逻辑最高bit开始分配BitField
u.B.y == 0b000001001 == 9
u.B.x == 0b0000111 == 7
这样,SmallEndian 和 BigEndian上,u.B.x 和 u.B.y的值一致
4. 实际上几乎任何情况下都不需要关心物理的bit序列, 应该说我们关心的是编译器对BitField的分配方式
阅读(1845) | 评论(0) | 转发(0) |