2017-02-17 28 views
2

私は違いが何であるかを理解することが好きでしたIntPtrとMarshal.ReadIntPtrの違いは何ですか?

new IntPtr(pointer.ToInt64() + 0x4); 

Marshal.ReadIntPtr(pointer + 0x4); 

彼らは異なる結果を与えるが、それは同じことをしませんか?

可能であれば、私の誤解を説明するための実用的な例を提供できますか?

+0

いいえ、最初にアドレスに4を加えて1000 + 4 = 1004とします.2番目は32ビット数(4バイト)を指すポインタです。ポインタポインタをインクリメントすると、一度に4バイト移動するので、1000 +(4 x 4バイト)= 1016となります。 – jdweng

+0

IntPtrは、メモリアドレスの格納によく使用されます。 2つのステートメントは非常に異なっています。第1のステートメントはアドレスを4だけインクリメントします。第2のステートメントも同様に速い方法で、*と*はメモリを読み取ります。メモリに格納されているポインタ値を取得すると考えられます。 –

答えて

1

IntPtrは、基本的にプラットフォーム固有の整数です。 32ビットOSでは32ビット、64ビットOSでは64ビットです。これはポインタを表すのによく使われますが、任意の整数を表すこともできます。

あなたの2つの方法は異なることを行います。最初(IntPtrコンストラクタ)は、あなたが提供する数値をそのまま取り、それをIntPtrとして表します。この場合、IntPtrが有効なメモリアドレスであるかどうかは関係ありません。

Marshal.ReadIntPtrは、メモリアドレスとして渡したものを処理し、そのアドレスに移動し、そこから4または8バイトを読み込み、そのデータを表すIntPtrを返します。

が確認するために、これを試してみてください:

IntPtr pointer = IntPtr.Zero; 
var anotherPointer = new IntPtr(pointer.ToInt64() + 0x4); 
var yetAnother = Marshal.ReadIntPtr(pointer + 0x4); 

あなたは、通常、低アドレス(0x4の)でメモリを読み取ることができないので、これは、3行目のメモリアクセス違反の例外がスローされます。二行目は、あなたが渡したもの(4)をIntPtrとして返します。

+0

こんにちはEvkは詳細な答えをくれてありがとうので、基本的に 'ReadIntPtr'は'新しいIntPtr(新しいIntPtr(...).ToInt64) 'を実行するようなものか、それとも間違った仮定ですか?彼らの記述と平等の面での意味です。私たちが正気のために32ビットでいるとします。 – Guapo

+0

いいえ、ReadIntPtrは指定したメモリ位置から整数値を読み込みます。たとえば、0x333333を提供します。それはメモリ位置0x333333に行き、そこから整数を読み込みます。任意の整数にすることができます。 IntPtrコンストラクタはメモリから何も読み込みません。これら2つの方法は完全に異なっており、お互いに関連していません。 – Evk

+0

私は、私はIntPtrもそれを読むという仮定の下にあった、返信のおかげで参照してください。効率が悪く、安全ではないMarhsal.ReadIntPtrは、最も速い、あるいは唯一のオプションですか、それとも他のオプションがありますか?もしあなたが知っている場合には、それにも返信しても大丈夫です。 – Guapo

関連する問題