从我所知,我发现的每个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添加示例?
答案 0 :(得分:1)
我认为关键是如果你溢出一个int,你仍然得到适当的值。试试这个:
//-2147483645
Console.WriteLine( int.MaxValue + 4 );
//2147483651
Console.WriteLine( (uint)(int.MaxValue + 4) );
鉴于int.MaxValue为2147483647,将溢出的负数转换为uint实际上会给出正确的值。
答案 1 :(得分:1)
.NET 4.0添加了一个新的静态方法IntPtr.Add(IntPtr指针,int offset)。
在早期的.NET版本中,转换为整数的另一种方法是使用“不安全”的代码块并将IntPtr转换为(byte *)。执行添加并将结果转回IntPtr。编译器负责指针宽度细节。 : - )
示例:
new IntPtr((byte *)pipe.Root + EventNameOffset)
或:
(IntPtr)((byte *)pipe.Root + EventNameOffset)
答案 2 :(得分:0)
在添加之前,IntPtr将转换为uint
,然后应用偏移量。这将正常工作,但结果是long
。
据我所知,无法添加ulong和int,因此64位指针部分不正确。实际上它甚至没有编译。我真的不能想到一个优雅的解决方案,但仅使用long
可能是安全的。这是你可以使用的内存的一半*,8 exabytes :)虽然内存地址映射在理论上可能是一个问题。
*:好吧,如果当前的.NET Framework实现不会阻止您在此之前 long :)