Java位解包程序与C不匹配
所以我得到了一个C程序,我正试图通过翻译成Java使其更具可移植性,这一直进展顺利。然而,我遇到了一些问题,我相信这部分代码就是其中之一。它只是一个解压30字节帧的函数。我有一种感觉,我在变量类型方面遇到了问题,试图找出最好的方法来为一些没有从C继承下来的Java类型划分子类型。如果有人看到了问题所在,我将不胜感激 爪哇:Java位解包程序与C不匹配,java,c,bit,pack,Java,C,Bit,Pack,所以我得到了一个C程序,我正试图通过翻译成Java使其更具可移植性,这一直进展顺利。然而,我遇到了一些问题,我相信这部分代码就是其中之一。它只是一个解压30字节帧的函数。我有一种感觉,我在变量类型方面遇到了问题,试图找出最好的方法来为一些没有从C继承下来的Java类型划分子类型。如果有人看到了问题所在,我将不胜感激 爪哇: 公共静态字节[]解包位(字节[]Src,整数位偏移量,字节[]Dst,整数位计数){ int srcbytepoffset,srcBit; int dstbytepoffse
公共静态字节[]解包位(字节[]Src,整数位偏移量,字节[]Dst,整数位计数){
int srcbytepoffset,srcBit;
int dstbytepoffset,dstBit;
字符掩码,srcMask;
srcByteOffset=位偏移/8;
srcBit=位偏移量%8;
srcMask=(char)(0x01您很可能偶然发现了一个非常常见的问题。根据运行C代码的机器的体系结构,C和java可能有不同的方式来表示int
通常,c程序应该将多字节整数转换为可移植性,就像您现在所做的那样
要获得正确的字节顺序,您必须使用and“and”运算符将位移位
同样令人感兴趣的是,该函数可以轻松处理通常由遗留c代码生成的LSB字节顺序整数。您很可能偶然发现了一个非常常见的问题。根据运行c代码的机器的体系结构,c和java可能有不同的方式表示int
通常,c程序应该将多字节整数转换为可移植性,就像您现在所做的那样
要获得正确的字节顺序,您必须使用and“and”运算符将位移位
同样令人感兴趣的是,具有轻松处理传统c代码通常产生的LSB字节顺序整数的功能。问题在于c没有一种内置方式来轻松访问字符*内的数据。unPackBits函数只是从特定位置(位偏移量)提取具有特定长度(位计数)的数据并以相同的形式返回。然后,数据必须转换为适当的类型,可以是bool、int、double等
另一方面,Java有一种处理相同问题的内置方法。存储在字节数组中的数据可以通过使用ByteBuffer.wrap(byte[])访问.ByteBuffer具有返回int、double、long、short、float和char的函数,以及用于放置所有这些类型的函数和其他一些有用的函数,如将整个结构转换为int数组。每个函数只需被告知偏移量,它们在内存中保存位计数。它不处理的唯一基本数据类型是boo精益,所以我仍然会使用字节数组解包,这不是一个问题,因为我知道这些值在数组中的确切位置
至于位移位,在将整个数组包装为ByteBuffer之前,按照@vidstige的建议,先移位整个数组,就像for循环中的第一个if-else所做的那样,一切都会井然有序。问题在于C没有一种内置的方式来轻松访问char*中的数据。unPackBits函数只是提取数据从具有特定长度(位计数)的某个位置(位偏移量)并以相同的形式返回。然后,必须将该数据转换为适当的类型,可以是bool、int、double等
另一方面,Java有一种处理相同问题的内置方法。存储在字节数组中的数据可以通过使用ByteBuffer.wrap(byte[])访问.ByteBuffer具有返回int、double、long、short、float和char的函数,以及用于放置所有这些类型的函数和其他一些有用的函数,如将整个结构转换为int数组。每个函数只需被告知偏移量,它们在内存中保存位计数。它不处理的唯一基本数据类型是boo精益,所以我仍然会使用字节数组解包,这不是一个问题,因为我知道这些值在数组中的确切位置
至于位移位,按照@vidstige的建议,在将整个数组包装为ByteBuffer之前,先移位整个数组,就像for循环中的第一个if-else那样,一切都会井然有序。每个版本的输出是什么?您是否尝试过打印中间变量并进行比较?我肯定我选择的打印不好,但是让我着迷的是大量无法解读的数据,我无法判断其中是否存在任何重大差异。简单解释一下……这件事实际上要做的是非常有用的——没有多少人会有耐心详细检查执行过程,并确保他们正确理解语义。当然C++中的一个字节[],一个带有位偏移的int,另一个字节[](类型是大多数时间),第二个int表示该信息是多少比特,然后返回第二字节[]中的未压缩(移位或倒置)位,在第二int中保存了任何长度。(它使用范围解析运算符:
),Java也比C更具可移植性?每个版本都有什么输出?你试过打印中间变量并进行比较吗?我确信我选择的打印方式很差,但让我受益的是大量无法识别的数据,我无法判断其中是否有任何主要差异。简单解释一下这件事……这件事实际上是在尝试什么g to do将非常有用-没有多少人会有耐心详细检查执行过程并确保他们理解正确的语义。当然,它需要一个字节[],一个带位偏移量的int,另一个字节[](大多数情况下都是类型转换)第二个int表示该信息的位数,然后返回第二个字节[]中的未压缩(移位或反转)位,第二个字节中保留的长度是多少
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;
}
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;
}
}
}