1

これまでのところ、受信した 8 バイトを UInt64 に変換するために行ったことは次のとおりです。

+ (UInt64)convertByteArrayToUInt64:(unsigned char *)bytes ofLength:(NSInteger)length
{
    UInt64 data = 0;

    for (int i = 0; i < length; i++)
    {
        data = data | ((UInt64) (bytes[i] & 0xff) << (24 - i * 8));
    }

    return data;
}

データを 8 バイトのデータに変換する送信者は、次のようにしました。

for(int i=1;i<9;i++)
{
    statusdata[i] = (time >> 8*i & 0xff);
}

受信した 8 バイトのデータ データは次のとおりです。

01 00 00 00 00 00 00 3b

私の方法の出力は次のとおりです。

16777216

この「16777216」を計算機を使用してバイトに変換しようとしたところ、次のようになりました。

01 00 00 00 00 00 00

これは、3b が変換に含まれていないことを意味します。

しかし、Javaでこのコードを試してみましたが、うまくいきました。どこに問題があるのか​​わからない。

助けてください。前もって感謝します!

4

1 に答える 1

4

AUInt64は 8 バイトなので、8 バイトのバッファーがある場合は、UInt64それへのポインターを作成して逆参照するだけです (データが x86 アーキテクチャーでリトルエンディアン形式である限り、それについて説明します)。秒で)、

そう:

unsigned char foo[8] = {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};

UInt64 *n = (UInt64 *) foo;  // pointer to value 0x0102030405060708

UInt64 nValue = *n;

ただし、x86 ハードウェアの個々のバイト値はリトル エンディアンであるため、最下位バイトがバッファ内で最初になることに注意してください。したがって、上記のバッファーを基数 16 の個々の数字と考えると、数値は次のようになります。

0x0102030405060708 (最上位バイトはバッファの最後です)。

ただし、探しているトリックは、単に 8 バイトのバッファーを にキャストしてUInt64*逆参照することです。ビッグエンディアンとリトルエンディアンのストレージ/バイトオーダーを見たことがない場合は、それについて読むことをお勧めします。

ps - 送信者コードが間違っています。配列インデックス ( i) は 0 から 7 まで実行する必要があるため、1 から 8(i=0;i<8;++i)ではなく、 の値がtime正しくコピーされません。ちなみに、送信者リトル エンディアン順 (バッファ内の最下位バイトが最初) にコピーしようとしていますtimeが、これも間違っています。statusdata

timeまた、送信側のコードが Java 上にある場合は、 の値が実際には負ではないことに注意する必要があります。Java には符号なし整数値がないため、timeが負の場合、それを UInt64 に再構成すると、大きな正の値になり、これは望ましくありません。

完全を期すために、リトル エンディアン バッファからバイト単位でデータを再構成する方法を示しますが、送信者コードが間違っているため、ゼロからインデックスに書き直す必要があることを思い出してください (そして型キャストを次のようにします)。上記のようにすると、そこにも到達します):

data = 0

for (i=0; i < 8; ++i) {
    data = (data << 8) | bytes[i];  // bytes is already UInt8 * so no need to mask it
}
于 2015-09-16T03:59:59.043 に答える