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]です。何が問題ですか?ありがとうございました。
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]です。何が問題ですか?ありがとうございました。
プラットフォームによって異なりますが、ビッグエンディアン/リトルエンディアンでは、バイトオーダーを変更する必要があります。
#ifdef _BIG_ENDIAN_
// revers bytes order
#endif
ntohs() は、バイト オーダーをビッグ エンディアンにスワップします。
ガブリエルが言ったように、
ntohs() は、u_short を TCP/IP ネットワーク バイト オーダーからホスト バイト オーダー (Intel プロセッサではリトル エンディアン) に変換します。
ntohs 関数は、ホストのバイト順で値を返します。渡されたパラメータがすでにホストのバイト順になっている場合、この関数はそれを逆にします。バイト順を逆にする必要があるかどうかを判断するのは、アプリケーション次第です。
他の人が指摘したように、投稿したコードは移植できません。エンディアンの理由だけではありません。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) };
内部表現を気にせずに書かれたコードが増えるといいですね!