3

FW 4.0以降、IntPtr構造には次のAddメソッドがあります。

public static IntPtr Add(
    IntPtr pointer,
    int offset
)

IntPtrこれは、私たちが持っていた数学に関するすべての質問(1、2、おそらくそれ以上)に対処することになっているので、素晴らしいことです

しかし、なぜoffset intですか?
そうではないIntPtrでしょうか?範囲を超える値で64ビットポインタをオフセットすることは容易に想像できintます。


たとえば、次のことを考慮してMarshal.OffsetOfください。

public static IntPtr OffsetOf(
    Type t,
    string fieldName
)

IntPtr構造体メンバーへのオフセットとしてを返します。これは完全に理にかなっています!Addまた、このオフセットを新しい方法で簡単に使用することはできません。にキャストしてから、ループで数回Int64呼び出す必要があります。Add

IntPtr.Sizeまた、適切に作成されたアプリケーションとは無関係であるという考えそのものを殺しているようです。オフセットをなどの特定のタイプにキャストするInt64必要があります。その時点で、サイズの違いの管理を開始する必要があります。そして、128ビットIntPtrが表示されたときに何が起こるかを想像してください。


ここでの私の質問は、なぜですか?
私は結論を正しているのでしょうか、それとも要点を見逃しているのでしょうか。

4

2 に答える 2

5

これは、x64アーキテクチャの制限に対応しています。相対アドレス指定は、符号付き32ビットオフセット値に制限されています。マット・ピエトレックはこの記事でこれについて言及しています(「幸いなことに、答えはノーです」の近く)。この制限は、.NETオブジェクトが64ビットモードで2GBに制限されている理由も説明しています。同様に、ネイティブx64 C / C ++コードでは、メモリ割り当ても制限されています。それが不可能であるというわけではありません。変位は64ビットレジスタに格納される可能性があります。これにより、配列のインデックス作成がはるかに高価になるだけです。

Marshal.OffsetOf()の不思議なリターンタイプはおそらくコーナーケースです。管理された構造体は、2GBを超える[StructLayout]と[MarshalAs]を適用した後、管理されていないバージョンになる可能性があります。

はい、これは将来の128ビットアーキテクチャにうまく対応できません。しかし、今日のソフトウェアをアーチ用に準備することは、それがどのようになるか誰にもわからない場合、非常に困難です。おそらく古い格言が当てはまるでしょう、16テラバイトは誰にとっても十分なはずです。そして、それを超えて成長する余地はたくさん残っています。2^64はかなり大きな数です。現在の64ビットプロセッサは2^48のみを実装しています。マシンがその近くに移動する前に、いくつかの深刻で重要な問題を解決する必要があります。

于 2010-11-24T14:40:16.097 に答える
1

定義する場合:

public static IntPtr Add(IntPtr pointer, IntPtr offset)

次に、64ビットポインタに32ビットオフセットを追加すると、読みにくくなります、IMHO。

繰り返しますが、

public static IntPtr Add(IntPtr pointer, long offset)

次に、32ビットポインタに64ビットオフセットを追加することも悪いことです。

ちなみに、SubstractはIntPtrを返すので、IntPtrロジックはとにかく壊れていません。

于 2010-11-24T14:13:18.783 に答える