Java位解包程序与C不匹配
所以我得到了一个C程序,我正试图通过翻译成Java使其更具可移植性,这一直进展顺利。然而,我遇到了一些问题,我相信这部分代码就是其中之一。它只是一个解压30字节帧的函数。我有一种感觉,我在变量类型方面遇到了问题,试图找出最好的方法来为一些没有从C继承下来的Java类型划分子类型。如果有人看到了问题所在,我将不胜感激
爪哇:
public static byte[] unPackBits(byte[] Src, int bitOffset, byte[] Dst, int bitCount){
int srcByteOffset, srcBit;
int dstByteOffset, dstBit;
char dstMask, srcMask;
srcByteOffset = bitOffset / 8;
srcBit = bitOffset % 8;
srcMask = (char)(0x01<<srcBit);
dstByteOffset = 0;
dstBit = 0;
dstMask = 0x01;
Dst[dstByteOffset] = '\0';
for(int b = 0; b < bitCount; b++){
if((Src[srcByteOffset] & srcMask) != (char)0x00){
Dst[dstByteOffset] = (byte)(Dst[dstByteOffset]|dstMask);
}
else {
Dst[dstByteOffset] = (byte)(Dst[dstByteOffset] & (~dstMask));
}
srcBit++;
if(srcBit < 8) {
srcMask = (char)(srcMask<<1);
}
else {
srcByteOffset++;
srcBit = 0;
srcMask = 0x01;
}
dstBit++;
if(dstBit < 8) {
dstMask = (char)(dstMask<<1);
}
else {
dstByteOffset++;
dstMask = 0x01;
dstBit = 0;
}
}
return Dst;
}
C:
void TRB::unPackBits(char *Src, int BitOffset, char *Dst, int BitCount) {
int srcByteOffset, srcBit;
int dstByteOffset, dstBit;
char dstMask, srcMask;
srcByteOffset = BitOffset / 8;
srcBit = BitOffset % 8;
srcMask = 0x01<<srcBit;
dstByteOffset = 0;
dstBit = 0;
dstMask = 0x01;
Dst[dstByteOffset] = '\0';
for(int b = 0; b < BitCount; b++) {
if((Src[srcByteOffset] & srcMask) != (char)0x00) {
Dst[dstByteOffset] = Dst[dstByteOffset] | dstMask;
}
else {
Dst[dstByteOffset] = Dst[dstByteOffset] & (~dstMask);
}
srcBit++;
if(srcBit < 8) {
srcMask = srcMask<<1;
}
else {
srcByteOffset++;
srcBit = 0;
srcMask = 0x01;
}
dstBit++;
if(dstBit < 8) {
dstMask = dstMask<<1;
}
else {
dstByteOffset++;
dstMask = 0x01;
dstBit = 0;
}
}
}
# 1 楼答案
问题是C没有一种内置的方式来轻松访问char*中的数据。unPackBits函数只是从特定位置(位偏移量)提取具有特定长度(位计数)的数据,并以相同的形式返回。然后,数据必须转换为适当的类型,可以是bool、int、double等
另一方面,Java有一种内置的方法来处理相同的问题。可以使用ByteBuffer访问存储在字节数组中的数据。换行(字节[])。ByteBuffer具有返回int、double、long、short、float和char的函数,以及用于放置所有这些类型的函数和其他一些有用的函数,例如将整个结构转换为int数组。每一个都只需要被告知偏移量,它们在内存中保留位计数。它唯一不处理的基本数据类型是布尔型,因此我仍然会使用字节数组解包,这不是一个问题,因为我确切地知道这些值在数组中的位置
至于位移位,按照@vidstige的建议,在将整个数组包装为ByteBuffer之前对其进行移位,就像for循环中的第一个if-else所做的那样,一切都会井然有序
# 2 楼答案
您很可能偶然发现了endianness的一个非常常见的问题。根据运行C代码的机器的体系结构,C和java可能有不同的方法来表示
int
典型的c程序应该将多字节整数转换成network byte order,以简化可移植性工作,就像您现在所做的那样
要获得正确的字节顺序,您必须使用bit-shift和“and”运算符对位进行移位
同样令人感兴趣的是nio package具有易于处理通常由遗留c代码生成的LSB字节顺序整数的功能