2017-02-17 114 views
2

我想了解的是什麼之間的區別:他們給了不同的結果IntPtr和Marshal.ReadIntPtr有什麼區別?

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

Marshal.ReadIntPtr(pointer + 0x4); 

,但它不是做同樣的事情?

如果可能,你能否提供一個實際的例子來說明我對它的誤解是什麼?

+0

否。首先是將4加到地址,所以1000 + 4 = 1004.其次是指向32位數(4字節)的指針。因此,當您增加指針指針時,一次移動4個字節,因此1000 +(4 x 4字節)= 1016. – jdweng

+0

IntPtr通常用於存儲內存地址。這兩個語句非常不同,第一個語句只是將地址遞增4。第二個語句也是這樣做的,快速的方法是*和*讀取內存。大概是檢索一個指針值,一個存儲在內存中的地址。 –

回答

1

IntPtr基本上是平臺特定的整數。它在32位操作系統中是32位,在64位操作系統中是64位。它通常用來表示一個指針,但也可以表示任何隨機整數。

所以你的兩個方法做不同的事情。首先(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)通常讀取內存。然而,第二行只是返回您通過那裏(4)的任何內容,如IntPtr

+0

嗨evk謝謝你的詳細答案,所以基本上你告訴我,''ReadIntPtr'會像'新的IntPtr(新的IntPtr(...)ToInt64)'跳過驗證或是一個錯誤的假設?我的意思是從他們的描述中獲得平等。爲了理智,我們說32位。 – Guapo

+0

不,ReadIntPtr將從您提供的內存位置讀取整數值。例如,你在那裏提供0x333333。它進入內存位置0x333333並從那裏讀取整數。它可以是任何整數。 IntPtr構造函數不會從內存中讀取任何內容。這兩種方法完全不同,完全不相關。 – Evk

+0

我明白了,我是在IntPtr也讀取它的前提下,謝謝你的回覆。在效率和不使用不安全,是Marhsal.ReadIntPtr最快或唯一的選擇可用或有其他的選擇嗎?如果你不介意的話,也可以在你知道的情況下回答。 – Guapo