gpt4 book ai didi

.net - 使用 Microsoft.Win32.SafeHandles 与 Marshal.AllocHGlobal 和 Marshal.FreeHGlobal

转载 作者:行者123 更新时间:2023-12-01 07:21:06 32 4
gpt4 key购买 nike

我有一个 .Net 类,它使用 structMarshal.AllocHGlobal 分配非托管内存,然后使用 Marshal.FreeHGlobal 处理它。

我知道类 Microsoft.Win32.SafeHandles 提供了处理这个的包装器,但不清楚如何实例化它们(许多没有构造函数) - 我应该编写抽象基类的特定实现还是有某种方法可以使用它们在 extern 声明中?

最佳答案

SafeHandle 进行子类化的主要问题是,对于 Marshal.DestroyStructure,您需要结构的 Type ......这使一切变得更加复杂。

您不能使用泛型(因为它们与 pinvoke 不兼容)...因此您可以拥有多个 SafeHandle 子类(每个 Type 一个),或者在 SafeHandle 中使用您手动设置的结构类型的属性。 .. 或者您可以使 SafeHandle 的构造函数接受要编码(marshal)的结构并在属性中设置 Type

我正在使用最后两个“选项”(可以手动设置或可以由构造函数自动设置的属性 Type)
MySafeHandle 示例:

public class MySafeHandle : SafeHandle
{
public Type Type { get; set; }

public MySafeHandle() : base(IntPtr.Zero, true)
{
}

public MySafeHandle(object obj)
: base(IntPtr.Zero, true)
{
if (obj != null)
{
Type = obj.GetType();
int size = Marshal.SizeOf(obj);

try
{
}
finally
{
// the finally part can't be interrupted by
// Thread.Abort
handle = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, handle, false);
}
}
}

public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}

[SecurityCritical]
protected override bool ReleaseHandle()
{
if (handle != IntPtr.Zero)
{
if (Type == null)
{
throw new InvalidOperationException();
}

try
{
}
finally
{
Marshal.DestroyStructure(handle, Type);
Marshal.FreeHGlobal(handle);
handle = IntPtr.Zero;
}

return true;
}

return false;
}
}

您应该使用的构造函数是使用 Marshal.StructureToPtr 编码结构的构造函数。它的优点是它保存了结构的类型,以便以后可以将其用于 Marshal.DestroyStructure

关于.net - 使用 Microsoft.Win32.SafeHandles 与 Marshal.AllocHGlobal 和 Marshal.FreeHGlobal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31020665/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com