IntPtr 加法

发布于 2024-08-10 04:03:40 字数 778 浏览 11 评论 0原文

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

So from what I can tell, every managed example of IntPtr addition I have found is WRONG.

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

My thought being, that if IntPtr is at (or near) int32.MaxValue on a 32-bit system, and you add an offset which overflows int32, isn't that still a valid memory address (as it would be valid in uint32, and would be represented by a negative number in IntPtr)?!

I believe the code should be something like:

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");
    }
}

Am I crazy?

Does anyone have a tried and true IntPtr addition example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄情伤 2024-08-17 04:03:40

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

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

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

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

I think the point is that if you overflow an int, you still get the appropriate value. Try this:

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

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

Given that int.MaxValue is 2147483647, casting the overflowed negative number to uint does in fact give the right value.

懷念過去 2024-08-17 04:03:40

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

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

示例:

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

或:

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

.NET 4.0 adds a new static method IntPtr.Add(IntPtr pointer, int offset).

On earlier .NET versions, an alternative method to converting to an integer is to use an 'unsafe' code block and cast the IntPtr to a (byte *). Perform your addition and turn the result back into an IntPtr. The compiler takes care of pointer width details. :-)

Example:

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

or:

  (IntPtr)((byte *)pipe.Root + EventNameOffset)
半步萧音过轻尘 2024-08-17 04:03:40

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

据我所知,ulong 和 int 的相加是不可能的,因此 64 位指针部分是不正确的。事实上它甚至无法编译。我真的想不出一个优雅的解决方案,但仅使用 long 可能是安全的。这是您可以使用的内存负载的一半*,8 艾字节:) 不过,内存地址映射理论上可能是一个问题。

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

Before addition, the IntPtr is cast to a uint, then the offset is applied. This will work correctly, but the result is a long.

As far as I know, addition of ulong and an int is not possible, so the 64-bit pointer part is incorrect. Indeed it doesn't even compile. I can't really think of an elegant solution, but just using a long instead would probably be safe. That's half of a sh*tload of memory you could use*, 8 exabytes :) Memory address mapping could theoretically be a problem there though.

*: well, if the current .NET Framework implementation wouldn't stop you from doing so long before that of course :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文