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实现不会阻止你在此之前很久就这样做:)