1

所以我得到了一个 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;
      }
   }

}
4

2 回答 2

1

您很可能偶然发现了一个非常常见的字节序问题。C 和 java可能有不同的方式来表示int取决于运行 c 代码的机器的体系结构。

通常,c 程序应将多字节整数转换为网络字节顺序,以简化可移植性工作,就像您现在所做的那样。

要获得正确的字节顺序,您必须使用位移位“与”运算符来移动位。

同样有趣的是 - nio 包具有轻松处理通常由传统 c 代码生成的 LSB 字节顺序整数的功能。

于 2011-06-22T20:06:12.023 回答
0

问题是 C 没有内置的方式来轻松访问 char * 中的数据。unPackBits 函数只是从某个位置(BitOffset)提取具有一定长度(BitCount)的数据并以相同的形式返回。然后必须将该数据转换为适当的类型,例如 bool、int、double 等。

另一方面,Java 具有处理相同问题的内置方法。可以使用 ByteBuffer.wrap(byte[]) 访问存储在字节数组中的数据。ByteBuffer 具有返回 int、double、long、short、float 和 char 的函数,以及用于放置所有这些类型和一些其他有用函数的函数,例如将整个结构转换为 int 数组。这些中的每一个只需要被告知偏移量,它们在内存中保存 BitCount。它唯一不处理的原始数据类型是布尔值,因此我仍将使用字节数组解包,这不是问题,因为我确切地知道这些值在数组中的位置。

至于位移,按照@vidstige 的建议,在将整个数组包装为 ByteBuffer 之前移动整个数组,就像 for 循环中的第一个 if else 一样,一切都会井井有条。

于 2011-06-24T16:37:54.077 回答