IntPtr addition

♀尐吖头ヾ 提交于 2020-01-03 03:04:13

问题


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?


回答1:


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.




回答2:


.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)



回答3:


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



来源:https://stackoverflow.com/questions/1706903/intptr-addition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!