【发布时间】:2011-12-06 08:32:33
【问题描述】:
我试着像这样投射它:
UIntPtr x = (UIntPtr)intPtr;
...但是编译器对此不太满意并返回了编译错误。
我需要进行转换,因为RegOpenKeyEx 的 P/Invoke 签名需要 UIntPtr:
[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定义RegOpenKeyEx而不是UIntPtr。 -
根据该站点:“将 IntPtr 更改为 UIntPtr:使用 IntPtr 调用句柄时,您将遇到溢出。如果您希望它在 32 和 64 上正常工作,UIntPtr 是正确的选择位平台。”
-
@Ian - 什么网站?除非它是微软的网站,否则我不会相信来源。 IntPtr 的大小取决于您使用的是 x86 还是 x64 操作系统。考虑到 C# 和 VB.NET 被编译到同一个 CLR 中,我应该指出,只有 C# 采用 UIntPtr,这看起来很奇怪。
-
@Ian:听起来不对。
IntPtr可以保存任何有效的指针值,即使是那些设置了高位的指针。无论如何,您不能对句柄值进行算术运算。
标签: c#