私は違いが何であるかを理解することが好きでしたIntPtrとMarshal.ReadIntPtrの違いは何ですか?
new IntPtr(pointer.ToInt64() + 0x4);
と
Marshal.ReadIntPtr(pointer + 0x4);
彼らは異なる結果を与えるが、それは同じことをしませんか?
可能であれば、私の誤解を説明するための実用的な例を提供できますか?
私は違いが何であるかを理解することが好きでしたIntPtrとMarshal.ReadIntPtrの違いは何ですか?
new IntPtr(pointer.ToInt64() + 0x4);
と
Marshal.ReadIntPtr(pointer + 0x4);
彼らは異なる結果を与えるが、それは同じことをしませんか?
可能であれば、私の誤解を説明するための実用的な例を提供できますか?
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
として返します。
こんにちはEvkは詳細な答えをくれてありがとうので、基本的に 'ReadIntPtr'は'新しいIntPtr(新しいIntPtr(...).ToInt64) 'を実行するようなものか、それとも間違った仮定ですか?彼らの記述と平等の面での意味です。私たちが正気のために32ビットでいるとします。 – Guapo
いいえ、ReadIntPtrは指定したメモリ位置から整数値を読み込みます。たとえば、0x333333を提供します。それはメモリ位置0x333333に行き、そこから整数を読み込みます。任意の整数にすることができます。 IntPtrコンストラクタはメモリから何も読み込みません。これら2つの方法は完全に異なっており、お互いに関連していません。 – Evk
私は、私はIntPtrもそれを読むという仮定の下にあった、返信のおかげで参照してください。効率が悪く、安全ではないMarhsal.ReadIntPtrは、最も速い、あるいは唯一のオプションですか、それとも他のオプションがありますか?もしあなたが知っている場合には、それにも返信しても大丈夫です。 – Guapo
いいえ、最初にアドレスに4を加えて1000 + 4 = 1004とします.2番目は32ビット数(4バイト)を指すポインタです。ポインタポインタをインクリメントすると、一度に4バイト移動するので、1000 +(4 x 4バイト)= 1016となります。 – jdweng
IntPtrは、メモリアドレスの格納によく使用されます。 2つのステートメントは非常に異なっています。第1のステートメントはアドレスを4だけインクリメントします。第2のステートメントも同様に速い方法で、*と*はメモリを読み取ります。メモリに格納されているポインタ値を取得すると考えられます。 –