2006年04月19日

いかに固定するか

日々拝読している akiramei さんの 匣の向こう側 - あまりに.NETな の記事で、Genericsとunsafe というのがあったのですが。

Marshal.UnsafeAddrOfPinnedArrayElement

これが勝利の鍵だ。

と言う結論ですが、これ間違いです。

MSDN の解説には次のように書かれています。

配列は、GCHandle を使用して pin を実行してあります。パフォーマンスを高めるため、このメソッドは渡された配列に対して一切の検証を行いません。この結果、予期しない動作につながることがあります。

分かりづらい文章ですね。原文だと極めて明快です。

The array must be pinned using a GCHandle before it is passed to this method.

このメソッドによって配列が自動的に固定されることはありません。配列を固定していない場合、このメソッドを呼び出した後に GC が起動して配列のアドレスが移動し、メソッドで取得したアドレスが無効になる可能性があります。

英文通り、事前に GCHandle.Alloc(object, GCHandleType.Pinned) で固定しなければいけません。で、GCHandle.Alloc したなら GCHandle.AddrOfPinnedObject メソッドを使うことで先頭アドレスが取得できます。

Alloc の第一引数はプリミティブなメンバしか含まない構造体でなければなりませんが、これの評価は実行時にされるので Generics でも問題なく使えます。

posted by Hongliang at 01:58| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。