1

そのため、私はCプログラムを受け取りました。これは、順調に進んでいるJavaに変換することで、より移植性を高めようとしています。しかし、私は少しのハングアップに遭遇しました。それはこのコードのビットにあると私は信じています。これは、30バイトのフレームを解凍する関数にすぎません。変数型の問題に直面しているような気がします。Cから引き継がれないJava型をサブ化する最善の方法を見つけようとしています。問題がどこにあるかを誰かが知っているなら、それをいただければ幸いです。

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は、Cコードを実行しているマシンのアーキテクチャに応じて、異なる方法で表現する場合があります。int

通常、cプログラムは、マルチバイト整数をネットワークバイトオーダーに変換して、現在行っているような移植性の作業を簡素化する必要があります。

バイト順序を正しくするには、ビットシフト演算子と「and」演算子を使用してビットをシフトする必要があります。

また興味深い-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 に答える