我正在尝试将 int32_t 编码为 C++ 中的字节数组,然后通过网络套接字将其传递给 java,并将其解码回始终为 32 位的 java 整数。
我已经使用以下代码成功地使用 16 位整数和无符号和有符号 16 位整数完成了此操作:
C++ 方面
void Codex::encodeShortToArray(uint16_t inputShort, unsigned char buffer[],int pos)
{
// insure its in network byte order
inputShort = htons(inputShort);
// encode the bytes
buffer[pos+1] = (inputShort >> 8);
buffer[pos+0] = inputShort;
}
Java 端:
public static short decodeShortFromArray(byte[] array, int pos)
{
return (short)
(
(array[pos+0] << 8)
+ (array[pos+1] & 0xff)
);
}
但是当我对 32 位整数进行同样的尝试时,它只适用于较小的无符号数。大数或有符号数在传输后返回不同的值。
C++ 方面
void Codex::encodeIntToArray(uint32_t inputInt, unsigned char buffer[],int pos)
{
// insure its in network byte order
inputInt = htonl(inputInt);
// encode the bytes
buffer[pos+3] = (inputInt >> 24);
buffer[pos+2] = (inputInt >> 16);
buffer[pos+1] = (inputInt >> 8);
buffer[pos+0] = inputInt;
}
Java 端:
public static int decodeIntFromArray(byte[] array, int pos)
{
return (int)
(
(array[pos+0] << 24)
+ (array[pos+1] << 16)
+ (array[pos+2] << 8)
+ (array[pos+3] & 0xff)
);
}
我假设对于四个字节,我需要不同的操作来按正确的顺序获取字节,但我对字节操作的掌握是有限的。
最佳答案
我相信您遇到的问题是字节是用 Java 签名的,而 <<
运算符将参数提升为整数。当您执行以下操作时:
array[pos] << 24
实际发生的事情更好地表达为:
(int)array[pos] << 24
如果array[pos]
(无符号)大于 127(即设置了最高有效位),然后 Java 会将其视为负数,然后您有额外的符号位被移位。
解决方案是屏蔽掉这些额外的位:
(array[pos] & 0xFF) << 24
// ^~~~~~
一个简单的例子:0x8000(无符号)是十进制的 32768。所以你会期望 0x80 << 8
给你 32768。尝试运行以下 Java 代码:
System.out.println(((byte)0x80) << 8);
System.out.println(((byte)0x80 & 0xFF) << 8);
当您屏蔽掉额外的符号位(第二个)时,您会得到预期的答案。
所以你的解码方法应该是:
public static int decodeIntFromArray(byte[] array, int pos)
{
return (int)
(
((array[pos+0] & 0xFF) << 24)
+ ((array[pos+1] & 0xFF) << 16)
+ ((array[pos+2] & 0xFF) << 8)
+ ((array[pos+3] & 0xFF)
);
}
关于java - 将 int32_t 编码为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23417810/