Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将IntPtr转换为UIntPtr?_C# - Fatal编程技术网

C# 如何将IntPtr转换为UIntPtr?

C# 如何将IntPtr转换为UIntPtr?,c#,C#,我试着这样做: UIntPtr x = (UIntPtr)intPtr; 。。。但是编译器对此不太满意,并返回了一个编译错误 我需要进行转换,因为的p/Invoke签名需要一个uintpttr: [DllImport("advapi32.dll", CharSet = CharSet.Auto)] public static extern int RegOpenKeyEx( UIntPtr hKey, string subKey, int ulOptions,

我试着这样做:

UIntPtr x = (UIntPtr)intPtr;
。。。但是编译器对此不太满意,并返回了一个编译错误

我需要进行转换,因为的p/Invoke签名需要一个uintpttr:

  [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
  public static extern int RegOpenKeyEx(
    UIntPtr hKey,
    string subKey,
    int ulOptions,
    int samDesired,
    out UIntPtr hkResult);
为了获得句柄,我使用SafeHandle.DangerousHandle()返回IntPtr:

   /// <summary>
    /// Get a pointer to a registry key.
    /// </summary>
    /// <param name="registryKey">Registry key to obtain the pointer of.</param>
    /// <returns>Pointer to the given registry key.</returns>
    IntPtr _getRegistryKeyHandle(RegistryKey registryKey)
    {
        //Get the type of the RegistryKey
        Type registryKeyType = typeof(RegistryKey);

        //Get the FieldInfo of the 'hkey' member of RegistryKey
        System.Reflection.FieldInfo fieldInfo =
            registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

        //Get the handle held by hkey
        SafeHandle handle = (SafeHandle)fieldInfo.GetValue(registryKey);

        //Get the unsafe handle
        IntPtr dangerousHandle = handle.DangerousGetHandle();
        return dangerousHandle;
    }
//
///获取指向注册表项的指针。
/// 
///获取的指针的注册表项。
///指向给定注册表项的指针。
IntPtr\u getRegistryKeyHandle(RegistryKey RegistryKey)
{
//获取注册表项的类型
类型registryKeyType=typeof(RegistryKey);
//获取RegistryKey的“hkey”成员的字段信息
System.Reflection.FieldInfo FieldInfo=
registryKeyType.GetField(“hkey”,System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
//把把手交给hkey
SafeHandle=(SafeHandle)fieldInfo.GetValue(registryKey);
//抓住不安全的把手
IntPtr dangerousHandle=handle.DangerousGetHandle();
返回危险手柄;
}

查看msdn后,我注意到,
UIntPtr
IntPtr
都有
void*
指针转换

IntPtr a = ....;
UIntPtr b = (UIntPtr)a.ToPointer();
此时,您需要不安全的代码。避免这种情况的唯一方法是使用
未选中的
关键字,并使用非指针类型(也使用)进行转换


两个指针之间没有转换的原因可能是
UIntPtr
IntPtr
类似,它们没有固定的大小,因为它们是特定于平台的().

我发现
位转换器
最可靠,因为它在使用VB.NET时也能工作,VB.NET不允许从有符号值溢出到无符号值:

new UIntPtr(BitConverter.ToUInt64(BitConverter.GetBytes(handleIntPtr.ToInt64), 0))

为什么不在32位指针上执行
unchecked((IntPtr)(int)uintpttr)
,或者在64位指针上执行
unchecked((IntPtr)(long)uintpttr)
?运行良好(并且比其他解决方案更快)。

IntPtr
可以保存与
UIntPtr
一样多的值。两者的位数相同

溢出是算术的一个概念。决不在句柄上执行算术运算。这一概念在这里不适用

在整个系统中,BCL
IntPtr
是手柄的标准类型。在任何地方使用
IntPtr

网站上说:

将IntPtr更改为UIntPtr:当使用IntPtr调用句柄时,您将遇到溢出。如果希望在32位和64位平台上正常工作,UIntPtr是正确的选择

很可能,他的代码以溢出的方式在类型之间转换。这只是他的一种迷信。他改变了一些事情。其中一个边使它起作用。他现在认为这是
IntPtr
的变化,但这是另外一回事


此外,这个选择与进程的比特性无关。

一个非常简单的解决方案,不需要不安全的代码,就是首先将指针强制转换为long,然后再转换为UIntPtr

IntPtr ptr = …;
UIntPtr Uptr = (UIntPtr)(long)ptr;

您尝试了什么,为什么需要转换?只需使用
IntPtr
定义
RegOpenKeyEx
,而不是
UIntPtr
。根据网站:将IntPtr更改为UIntPtr:当使用IntPtr调用句柄时,您将遇到溢出。如果希望在32位和64位平台上正常工作,UIntPtr是正确的选择。“@Ian-什么网站?除非是微软的网站,否则我不会相信消息来源。IntPtr的大小取决于您是在x86还是x64操作系统上工作。我应该指出,考虑到C#和VB.NET被编译到同一个CLR中,只有C#接受UIntPtr,这似乎很奇怪。@Ian:听起来不对
IntPtr
可以保存任何有效的指针值,即使是设置了高位的指针值。无论如何,您不能对句柄值进行算术运算。