IntPtr补充

时间:2009-11-10 10:16:34

标签: c# .net interop 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添加示例?

3 个答案:

答案 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 :)