IntPtr补充

所以从我所知道的,我发现的IntPtr添加的每个托管示例都是错误的

例如: http : //www.atalasoft.com/cs/blogs/stevehawley/archive/2006/10/16/10987.aspx

我的想法是,如果IntPtr在32位系统上(或接近)int32.MaxValue,并且你添加一个溢出int32的偏移量,那么它仍然是一个有效的内存地址(因为它在uint32中是有效的,并将由IntPtr中的负数表示?)!

我相信代码应该是这样的:

public static IntPtr Offset(IntPtr src, int offset) { switch (IntPtr.Size) { case 4: return new IntPtr((int)((uint)src + offset)); case 8: return new IntPtr((long)((ulong)src + offset)); default: throw new NotSupportedException("Not supported"); } } 

我疯了吗?

有没有人有一个久经考验的IntPtr加法例子?

我认为关键是如果你溢出一个int,你仍然得到适当的值。 试试这个:

 //-2147483645 Console.WriteLine( int.MaxValue + 4 ); //2147483651 Console.WriteLine( (uint)(int.MaxValue + 4) ); 

鉴于int.MaxValue是2147483647,将溢出的负数转换为uint实际上确实给出了正确的值。

.NET 4.0添加了一个新的静态方法IntPtr.Add(IntPtr指针,int offset)。

在早期的.NET版本中,转换为整数的另一种方法是使用“不安全”的代码块并将IntPtr转换为(byte *)。 执行添加并将结果转回IntPtr。 编译器负责指针宽度细节。 🙂

例:

  new IntPtr((byte *)pipe.Root + EventNameOffset) 

要么:

  (IntPtr)((byte *)pipe.Root + EventNameOffset) 

在添加之前,将IntPtr强制转换为uint ,然后应用偏移量。 这将正常工作,但结果很long

据我所知,无法添加ulong和int,因此64位指针部分不正确。 实际上它甚至没有编译。 我真的不能想到一个优雅的解决方案,但只是使用long而不是可能是安全的。 这是你可以使用的内存的一半*,8 exabytes :)虽然内存地址映射在理论上可能是一个问题。

*:好吧,如果当前的.NET Framework实现不会阻止你在此之前很久就这样做:)