2011-12-29 6 views
4

あり、私が読んでいるいくつかのコードだと、それの一部である:私はそれだけでバイト配列にユニットの位置に4つのバイトを入れているが、私はどのように明確ではないんだということを理解固定ポインタ文?

public static unsafe byte[] GetBytes(uint value, bool BigEndian) 
    { 
     byte[] buff = new byte[4]; 
     fixed (byte* pbyte = buff)*((uint*)pbyte) = value; 
     if (BigEndian) 
      buff.EndianConvert(); 
     return buff; 
    } 

それの私の理解では、ということです。

(uint*)pbyte 

がUINTポインタにPBYTEのアドレスをキャストし、

(byte* pbyte = buff) 

を作成し、バフのアドレスを指すバイトポインタPBYTEを返します?、

私はそれ以外の部分は理解していません。固定キーワードの使い方は?

(byte* pbyte = buff) = (byte*)value; 

答えて

1

他にもピンニングの概念が説明されていますが、あなたが混乱しているのは、すべてが1行にあるということです。

fixed (byte* pbyte = buff)*((uint*)pbyte) = value; 

に相当します。この同じよう

fixed (byte* pbyte = buff) 
{ 
    *((uint*)pbyte) = value; 
} 

if(someCondition) DoSomething(); 

は同等です:

if(someCondition) 
{ 
    DoSomething(); 
} 

アップ、それそれが明確にしていますか?最初の部分は変数と関連ブロックの宣言であり、2番目の部分は代入であることは明らかです。

+0

ありがとう、それはそれをクリアします。私は宣言が式の一部であると思った。 – mowwwalker

+0

@Walkerneo:正直言って、それも私を最初に投げ入れた。私は(それを考えていると思うが)私はC#に精通している。私はその行を二度見なければならなかったが、スペースがないとそれはかなり醜い。 –

2

固定ステートメントは、ガベージコレクタが可動変数を再配置できないようにします。省略した場合、アドレスが変更され、エラーが発生する可能性があります。

1

ガベージコレクタによって管理されているため、メモリ内の場所が変更される可能性があるため、時間。 fixedキーワードは、スコープの持続時間の間、配列の位置を固定し、配列の4バイトが(4バイト)のuint値で埋められるようにします。

+0

この声明はどのように機能していますか? – mowwwalker

0

通常のGCヒープオブジェクト(LOHを除く)のCLR GCプロセスでは、GCがマークし、次の世代に移動します(このアクションも昇格という名前になります)。オブジェクトAを宣言すると、GCはオブジェクトAのアドレスをaddr-oldからaddr-newに変更し、このオブジェクトを参照するすべてのオブジェクトの関係を更新します。

たとえば、オブジェクトAはオブジェクトBとオブジェクトCによって参照されます。つまり、オブジェクトBはオブジェクトAを指すポインタを持ち、オブジェクトCもオブジェクトAを指すポインタを持ちます。オブジェクトAのアドレスがaddr-oldからaddr-newに変更されると、GCはオブジェクトBとオブジェクトCの参照ポインタ値も変更します。変更後、オブジェクトBとCは正しいポインタを持ちます今はAを指していた。

"byte * pbyte = buff"行が実行された後、pbyteはオブジェクト "buff"を指すポインタを持ちます.pbyteアドレスが0x12345678であるとしましょう(buff addrは0x12345678も意味します)。そして今、GCが発生しました。オブジェクト "buff"は新しい世代に昇格されます。つまり、オブジェクト "buff"は新しいメモリアドレスを持ちます。例えば、 "0x55555555"です。しかし、 "pbyte"はネイティブ(アンマネージド)オブジェクトであり、CLRはそのライフサイクルを維持する方法を知らないため、pbyteはbuffと関係がありますが、CLRはpbyteアドレスを0x12345678から0x55555555に変更できません。次に、ポインタ "pbyte"はまだアドレス0x12345678を指していますが、このアドレスはオブジェクト "buff"に属しません。ポインタ "pbyte"は現在悪いポインタです。

"fixed"ステートメントは、管理対象オブジェクト "buff"が昇格されないようにします。また、ここから移動することもありません。

+0

素晴らしいです、ありがとう!それは固定キーワードを説明しますが、私はまだこのステートメントのロジックを理解していません。どのようにpbyteポインタに値のアドレスを割り当てるのですか?どのように機能するのですか? – mowwwalker

+0

メソッドはGetBytes(uint value、bool BigEndian)です.1番目のパラメータは4バイトオブジェクトであるuint値でなければなりません。そのため、このメソッドは4バイトのバッファーを割り当て、最初にuint *型にポインタ "pbyte"をキャストし、その型にuint型の "value"を割り当てます。最後に、このメソッドは "安全でない"バッファを安全でない他のメソッドに返します。 –