我有一个要求,需要在二进制协议中填充3个字节(24位)。原始值存储在int(32位)中。实现这一目标的一种方法如下: -
Technique1: -
long x = 24;
long y = htonl(x);
long z = y>>8;
memcpy(dest, z, 3);
如果以上是正确的方法,请告诉我?
另一种方式,我不明白实施如下
Technique2: -
typedef struct {
char data1;
char data2[3];
} some_data;
typedef union {
long original_data;
some_data data;
} combined_data;
long x = 24;
combined_data somedata;
somedata.original_data = htonl(x);
memcpy(dest, &combined_data.data.data2, 3);
我不明白的是,如果3个字节最后在combined_data.data.data2中而不是第一个字节应该进入combined_data.data.data1,接下来的2个字节应该进入 combined_data.data.data2?
这是x86_64平台,运行2.6.x linux和gcc。
部分解决: - 在x86_64平台上,内存从右到左进行寻址。因此,值为24的long类型的变量将具有以下内存表示
|--Byte4--|--Byte3--|--Byte2--|--Byte1--|
0 0 0 0x18
对上面的long类型执行htonl(),内存变为
|--Byte4--|--Byte3--|--Byte2--|--Byte1--|
0x18 0 0 0
在struct some_data中,
data1 = Byte1
data2[0] = Byte2
data2[1] = Byte3
data4[2] = Byte4
但是我的问题仍然存在,为什么不如技术1所示简单地右移8?
答案 0 :(得分:2)
一个字节需要8位: - )
int x = 24;
int y = x<<8;
移动0,你什么都没改变。 1 - * 2,2 - * 4,8 - * 256。
如果我们在BIG ENDIAN机器上,4个字节被放入内存中,因为:2143。并且这样的算法不适用于大于2 ^ 15的数字。另一方面,在BIG ENDIAN机器上你应该定义,“将整数放在3个字节中”是什么意思
嗯。我想,第二个提出的algorythm会好的,但是改变字节的顺序:
你有他们2143.我想你需要321。但最好检查一下。
编辑:我查了wiki - x86是小端,他们说,所以algorythms没关系