0
unsigned short* pname = (unsigned short*)(buf + buf_offset);/*sequence problem?*/
unsigned short pointer_offset = ntohs(*pname) & COMPRESSION_MASK;

ここで、buf_offset ==0です。bufの内容は[c0][0c]です。ただし、*pnameは[0x0cc0]です。何が問題ですか?ありがとうございました。

4

4 に答える 4

0

プラットフォームによって異なりますが、ビッグエンディアン/リトルエンディアンでは、バイトオーダーを変更する必要があります。

#ifdef _BIG_ENDIAN_ 
    // revers bytes order
#endif
于 2013-03-15T04:26:04.497 に答える
0

ntohs() は、バイト オーダーをビッグ エンディアンにスワップします。

于 2013-03-15T04:26:21.000 に答える
0

ガブリエルが言ったように、

ntohs() は、u_short を TCP/IP ネットワーク バイト オーダーからホスト バイト オーダー (Intel プロセッサではリトル エンディアン) に変換します。

ntohs 関数は、ホストのバイト順で値を返します。渡されたパラメータがすでにホストのバイト順になっている場合、この関数はそれを逆にします。バイト順を逆にする必要があるかどうかを判断するのは、アプリケーション次第です。

于 2013-03-15T06:04:51.790 に答える
0

他の人が指摘したように、投稿したコードは移植できません。エンディアンの理由だけではありません。char *からへのキャストunsigned short *も、無効なアラインメントが原因でバス エラーを引き起こす可能性があります。unsigned shortさらに、プログラムの誤動作の原因となるパディング ビットが に含まれている場合や、実装の選択にunsigned short応じて、 が「2 バイト」よりも小さい場合や大きい場合があります。CHAR_BIT全体的な問題は型の内部表現であり、内部表現に関係なく同じように動作する演算子を使用することで、この問題を回避できます。おそらくあなたは次のことを意味しました:

unsigned short offset = (unsigned char) buf[0];
offset *= (UCHAR_MAX + 1);
offset += (unsigned char) buf[1];
offset &= COMPRESSION_MASK;

ビッグ エンディアンが必要な場合は、それが必要であることを明示的に示す必要があります。を乗算buf[0]して加算することで、が よりも重要でbuf[1]あることを指定しているため、ビッグ エンディアンが必要であることを明示的に指定しています。乗算と加算はすべての C 実装で同じように機能し、アラインメントの問題はありません。buf[0]buf[1]

変換を逆にする:

unsigned char buf[2] = { offset / (UCHAR_MAX + 1), offset % (UCHAR_MAX + 1) };

内部表現を気にせずに書かれたコードが増えるといいですね!

于 2013-03-15T04:40:49.190 に答える