注意:问题不在于我使用指针和不安全的代码; 代码工作得很好.该问题与确认的编译器错误有关,该错误在某些情况下拒绝编译法律代码.如果您对该问题感兴趣,请访问我的其他问题
因为我的问题是指针变量的声明,所以我决定解决这个问题,然后使用IntPtr,并在需要时转换为实际的指针.
但是,我注意到我做不到这样的事情:
IntPtr a = something;
IntPtr b = somethingElse;
if (a > b) // ERROR. Can't do this
{
}
Run Code Online (Sandbox Code Playgroud)
在>和<似乎运营商没有为被定义IntPtr.请注意,我确实可以比较两个实际指针.
IntPtr有一个.ToInt64()方法.但是,这会返回一个有符号值,在与之比较时可能会返回不正确的值,>并且<当涉及正值和负值时.
说实话,我真的不明白.ToInt64()对于返回有符号值的方法有什么用处,考虑到指针比较是无符号执行的,但这不是我的问题.
有人可能会争辩说,IntPtrs为不透明的手柄,这是毫无意义的,因此与比较>和<.但是,我会指出IntPtr有加法和减法的方法,这意味着实际上存在秩序概念IntPtr,因此>并且<确实有意义.
我想我可以将结果转换ToInt64()为a ulong然后进行比较,或者将其IntPtr转换为指针,然后进行比较,但它让我想到为什么不是>和<定义的IntPtr.
为什么我不能IntPtr直接比较两个?
IntPtr一直有点被忽视.直到.NET 4.0,甚至没有Add/ operator+和Subtract/ operator-.
现在......如果你想比较两个指针,long如果它们是一个IntPtr或者ulong它们是什么,则将它们转换为UIntPtr.请注意,在Windows上,UIntPtr如果您使用带有该/3GB选项的32位程序,则只需要一个,因为否则32位程序只能使用较低的2gb地址空间,而对于64位程序,则远小于64位地址使用空格(此时为48位).
显然,如果你在.NET中进行内核编程,这会改变:-)(我在这里jocking,希望:-))
由于为什么IntPtr首选的原因UIntPtr:https://msdn.microsoft.com/en-us/library/system.intptr%28v=vs.110%29.aspx
IntPtr类型符合CLS,而UIntPtr类型则不符合.在公共语言运行库中仅使用IntPtr类型.提供UIntPtr类型主要是为了保持IntPtr类型的架构对称性.
有些语言没有区分有符号和无符号类型..NET想要支持它们.
通过使用完成一些测试
editbin /LARGEADDRESSAWARE myprogram.exe
Run Code Online (Sandbox Code Playgroud)
(我甚至能够崩溃我的图形适配器:-))
static void Main(string[] args)
{
Console.WriteLine("Is 64 bits", Environment.Is64BitProcess);
const int memory = 128 * 1024;
var lst = new List<IntPtr>(16384); // More than necessary
while (true)
{
Console.Write("{0} ", lst.Count);
IntPtr ptr = Marshal.AllocCoTaskMem(memory);
//IntPtr ptr = Marshal.AllocHGlobal(memory);
lst.Add(ptr);
if ((long)ptr < 0)
{
Console.WriteLine("\nptr #{0} ({1}, {2}) is < 0", lst.Count, ptr, IntPtrToUintPtr(ptr));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我能够使用32位程序(在64位操作系统上)分配近4 GB的内存(所以我有负面IntPtr)
这里,它是从铸造IntPtr到UIntPtr
public static UIntPtr IntPtrToUintPtr(IntPtr ptr)
{
if (IntPtr.Size == 4)
{
return unchecked((UIntPtr)(uint)(int)ptr);
}
return unchecked((UIntPtr)(ulong)(long)ptr);
}
Run Code Online (Sandbox Code Playgroud)
请注意,由于符号扩展如何工作,你不能简单地做(UIntPtr)(ulong)(long)ptr,因为在32位它会破坏.
但请注意,很少有程序在32位上支持> 2 gb ... http://blogs.msdn.com/b/oldnewthing/archive/2004/08/12/213468.aspx
| 归档时间: |
|
| 查看次数: |
1928 次 |
| 最近记录: |