1

因此,据我所知,我发现的每个 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 添加示例?

4

3 回答 3

1

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

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

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

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

于 2009-11-10T10:49:39.090 回答
1

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

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

例子:

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

或者:

  (IntPtr)((byte *)pipe.Root + EventNameOffset)
于 2010-04-22T16:03:34.313 回答
0

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

据我所知,添加 ulong 和 int 是不可能的,所以 64 位指针部分是不正确的。事实上,它甚至没有编译。我真的想不出一个优雅的解决方案,但只使用 along可能是安全的。这是您可以使用的内存的一半*,8 EB :) 内存地址映射理论上可能是一个问题。

*: 好吧,如果当前的 .NET Framework 实现不会阻止你在此之前这么长时间做的话:)

于 2009-11-10T10:31:35.570 回答