c# - 新的 IntPtr.Add 方法 - 我是否错过了 int 的要点?

标签 c# .net .net-4.0 intptr pointer-arithmetic

从固件 4.0 开始,IntPtr structureAdd方法:

public static IntPtr Add(
    IntPtr pointer,
    int offset
)

这很棒,因为它应该解决我们遇到的关于 IntPtr 数学的所有问题( 12 ,可能更多)。

但是为什么offsetint
一定不是IntPtr吗?我可以轻松想象将 64 位指针偏移超出 int 范围的值。

<小时/>

例如,考虑 Marshal.OffsetOf :

public static IntPtr OffsetOf(
    Type t,
    string fieldName
)

它返回一个IntPtr作为结构成员的偏移量。这很有道理!并且您无法通过新的 Add 方法轻松使用此偏移量。您必须将其转换为 Int64,然后在循环中多次调用 Add

此外,它似乎消除了 IntPtr.Size 与正确编写的应用程序无关的想法。您必须将偏移量转换为特定类型,例如 Int64,此时您必须开始管理大小差异。想象一下当 128 位 IntPtr 出现时会发生什么。

<小时/>

我的问题是,为什么?
我的结论是正确的,还是我没有捕获重点?

最佳答案

它对应于 x64 架构中的限制。相对寻址仅限于带符号的 32 位偏移值。 Matt Pietrek 在 this article 中提到了这一点(靠近“幸运的是,答案是否定的”)。此限制也解释了为什么 .NET 对象在 64 位模式下仍限制为 2GB。同样,在 native x64 C/C++ 代码中,内存分配也受到限制。并不是说不可能,位移可以存储在 64 位寄存器中,只是这会使数组索引变得很多更加昂贵。

Marshal.OffsetOf() 神秘的返回类型可能是一个极端情况。应用大于 2GB 的 [StructLayout] 和 [MarshalAs] 后,托管结构可能会产生非托管版本。

是的,这不能很好地映射到 future 的某些 128 位架构。但是,当没有人知道它会是什么样子时,为当今的拱门准备软件是非常困难的。也许古老的格言很合适,16 TB 对任何人来说都应该足够了。除此之外,还有很多的增长空间,2^64 是一个相当大的数字。当前的 64 位处理器仅实现 2^48。在机器能够移动得那么近之前,需要解决一些严重的、不平凡的问题。

关于c# - 新的 IntPtr.Add 方法 - 我是否错过了 int 的要点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4267531/

相关文章:

c# - C# 可以反射(reflect) VB.NET .dll 程序集吗

.NET 4.0 : Is it possible to call ConvertAll for IList<>?

c# - 如何在 Visual Studio 中引用 CSS 背景图片?

asp.net - 如何使用 LinkBut​​ton 提交表单?

c# - 从另一个类或 c# 中的静态方法更改 wpf 元素/控件

c# - 如何通过 UnhandledException 卸载 AppDomain

c# - 在 .NET 4.0 中,如何 'sandbox' 一个内存程序集并执行一个方法?

c# - 将一个数旋转 180 度,得到相同的数

C# EPPlus OpenXML 计数行

c# - 连接到 Com5 : System. NullReferenceException 未处理