无法在 C# 中取消引用 IntPtr

本文关键字:取消 引用 IntPtr | 更新日期: 2023-09-27 18:37:10

我写了一个在COM中实现IGroupPolicyObject Interface的类。其中一个方法现在在 C# 中返回 IntPtr 对象:

IntPtr ghKey = objectGPolicy.GetRegistryKey(GpoSectionMachine);

我想在使用属于Microsot.Win32命名空间的RegistryKey对象时取消引用该指针。

这不起作用:

(RegistryKey)ghKey = rootKey.CreateSubKey(policyPath);

我找不到如何取消对 Intptr 的引用。有人可以帮忙吗?

谢谢

无法在 C# 中取消引用 IntPtr

IGroupPolicyObject.GetRegistryKey

返回 .NET RegistryKey 对象,它返回 Win32 注册表项句柄(HKEY)。对于包含本机 HKEY 的 IntPtr 值,可以执行两项有用的操作。首先,可以将其传递给其他 Win32 注册表访问函数。如果以这种方式使用它,则还需要在完成后通过调用RegCloseKey来手动关闭它,否则它将泄漏句柄。

正如@HansPassant在他的评论中有帮助地指出的那样,您的第二个(可能更好)选择是将其转换为SafeRegistryHandle并使用它来获取RegistryKey对象:

var hkey = gpo.GetRegistryKey(GpoSectionMachine);
var safeHandle = new SafeRegistryHandle(hkey, true);
var reg = RegistryKey.FromHandle(safeHandle);

如果您编写了 IGroupPolicyObject 的托管实现,并且它从此函数返回实际的 RegistryKey 对象,则:

  1. 你做错了,你的实现不能移植到IGroupPolicyObject的任何其他消费者,并且
  2. 您必须在实现中手动将RegistryKey对象编组到IntPtr,因此只需执行相反的操作即可将其重新取出。(但实际上 - 不要这样做,你通过返回错误的类型来破坏 COM 协定。

应该编写此方法的实现以返回SafeRegistryHandle(我相信封送拆收器会自动在SafeHandle和非托管句柄之间进行转换)。 RegistryKey.Handle 就是其中之一,因此你可以一直使用 C# 类,直到需要从实现中返回一些内容。