RegOpenKeyEx
当我注意到页面上的这条评论时,我正在查看 P/Invoke 声明:
更改
IntPtr
为UIntPtr
:当IntPtr
为句柄调用时,您将遇到溢出。UIntPtr
如果您希望它在 32 位和 64 位平台上正常工作,是正确的选择。
这对我来说没有多大意义:两者IntPtr
都UIntPtr
应该表示指针,因此它们的大小应该与操作系统的位数相匹配——32 位或 64 位。由于这些不是数字而是指针,因此它们的带符号数值无关紧要,只有表示它们指向的地址的位。我想不出为什么这两者之间会有区别,但是这个评论让我不确定。
是否有特定的理由使用UIntPtr
而不是IntPtr
?根据文档:
IntPtr
类型符合 CLS,而类型UIntPtr
不符合。只有IntPtr
类型在公共语言运行时中使用。提供该UIntPtr
类型主要是为了与该类型保持体系结构对称IntPtr
。
当然,这意味着没有区别(只要有人不尝试将值转换为整数)。那么上面来自 pinvoke.net 的评论不正确吗?
编辑:
在阅读了 MarkH 的回答后,我做了一些检查,发现 .NET 应用程序不支持大地址,在 32 位模式下编译时只能处理 2GB 的虚拟地址空间。(可以使用hack来打开大地址感知标志,但 MarkH 的回答表明 .NET Framework 内部的检查会破坏事情,因为地址空间被假定为只有 2GB,而不是 3GB。)
这意味着指针可以拥有的所有正确虚拟内存地址(就 .NET Framework 而言)将介于 0x00000000 和 0x7FFFFFFF 之间。当这个范围被转换为有符号int
时,没有值会是负数,因为最高位没有设置。这强化了我的信念,即使用 IntPtr 和 UIntPtr 没有区别。我的推理正确吗?
Fermat2357 指出上面的编辑是错误的。