12

C# はエンディアンに敏感ですか? たとえば、次のようなコードになります。

int a = 1234567;
short b = *(short*)&i;

常に同じ値を b に割り当てます。もしそうなら、それはどのような値になりますか?

そうでない場合、ポインターを含むコードの場合、エンディアンに対処するための良い方法は何ですか?

4

4 に答える 4

15

C# はエンディアンを定義しません。実際には、おそらく常にリトル エンディアンになります (IA64 でも IIRC ですが、私は確認していません) が、理想的にBitConverter.IsLittleEndianはエンディアンが重要かどうかを確認する必要があります。または、直接メモリ アクセスではなくビット シフトなどを使用する必要があります。

protobuf-net (まだコミットされていないビルド) から数行を引用するには:

WriteInt64(*(long*)&value);
if (!BitConverter.IsLittleEndian)
{   // not fully tested, but this *should* work
    Reverse(ioBuffer, ioIndex - 8, 8);
}

つまり、エンディアンをチェックし、必要に応じて反転します。

于 2010-02-11T21:41:21.913 に答える
6

はい、コードエンディアンに依存していると思います。の値はb、リトル エンディアン プロセッサでは最下位バイトになり、ビッグ エンディアン プロセッサでは最上位バイトになります。これを見やすくするために、16 進数に切り替えましょう。

using System;

class Test
{
    unsafe static void Main()
    {
        int a = 0x12345678;
        short b = *(short*)&a;
        Console.WriteLine(b.ToString("x"));
    }
}

私のx86ボックスでは、「5678」が出力され、最下位バイトが値の「開始」にあったことを示していますa. ビッグエンディアン モード (おそらく Mono) で実行されているプロセッサで同じコードを実行すると、"1234" が出力されると思います。

于 2010-02-11T21:43:13.347 に答える
1

私が知る限り、C# と共通言語インフラストラクチャの仕様のどちらにも、ポインター ベースのビット演算と数学演算のエンディアン要件はありません。CLI は、MSIL 実行可能ファイルに格納されたバイナリ データはリトル エンディアン形式でなければならないと述べています。また、ドキュメントの一般的なドリフトは、特別な状況を除いて、コードが特定のメモリ表現 (パックまたはアンパック配列などを含む) に依存してはならないことを示しています。

于 2010-02-11T22:02:43.143 に答える
-3

C# でポインターのスウィズリングを行うべきではありません。コードが何をするかを尋ねる前に、コードをコンパイルしてみる必要があります。

于 2010-02-11T21:40:46.887 に答える