2010-11-24 27 views
2

從FW 4.0開始,IntPtr structureAdd方法:新的IntPtr.Add方法 - 我錯過了int的點嗎?

public static IntPtr Add(
    IntPtr pointer, 
    int offset 
) 

這是偉大的,因爲它應該解決的IntPtr數學,我們有所有這些問題(12,可能更多)。

但爲什麼是offsetint
是否必須爲IntPtr?我可以很容易地想象一個超出int範圍的值偏移64位指針。


例如,考慮Marshal.OffsetOf

public static IntPtr OffsetOf(
    Type t, 
    string fieldName 
) 

它返回一個IntPtr作爲偏移到所述結構構件。這非常合理!你不能輕易使用這個偏移量和新的Add方法。您必須將其投射到Int64,然後在循環中多次撥打Add

此外,它似乎殺死了IntPtr.Size的想法與正確書面申請無關。您必須將偏移量轉換爲特定類型,例如Int64,此時您必須開始管理大小差異。和圖像128位IntPtr出現時會發生什麼。


這裏我的問題是,爲什麼?
我的結論是否正確?還是我錯過了觀點?

回答

5

它對應於x64架構中的限制。相對尋址限於一個帶符號的32位偏移量值。 Matt Pietrek在this article(接近「幸運的是,答案是否定的」)中提到了這一點。此限制還解釋了爲什麼.NET對象在64位模式下仍然限制爲2GB。同樣,在原生x64 C/C++代碼中,內存分配也受到限制。這不是不可能的,位移可以存儲在一個64位的寄存器中,只是這會使數組索引更昂貴。

Marshal.OffsetOf()的神祕返回類型可能是一個角落案例。託管結構在應用大於2GB的[StructLayout]和[MarshalAs]之後可能導致非託管版本。

是的,這將不能很好地映射到未來的128位體系結構。但是,當沒有人知道它的外觀時,爲今天的拱門準備軟件是非常困難的。也許這句古老的諺語是合適的,16TB對任何人都應該是足夠的。而且還有地段的剩餘空間超過這個數字,2^64是一個很大的數字。目前的64位處理器僅實現2^48。在機器移動之前需要解決一些嚴重不平凡的問題。

1

如果只定義:

public static IntPtr Add(IntPtr pointer, IntPtr offset) 

然後,加入32位偏移量爲64位指針是少可讀,IMHO。

同樣,如果定義

public static IntPtr Add(IntPtr pointer, long offset) 

然後,加入64位偏移到一個32位指針也很糟糕。

順便說一下,摘要返回一個IntPtr,所以IntPtr邏輯不會被打破。

相關問題