使用 Microsoft.Win32.SafeHandles 与 Marshal.AllocHGlobal 和 Marshal.FreeHGlobal
Using Microsoft.Win32.SafeHandles vs Marshal.AllocHGlobal and Marshal.FreeHGlobal
我有一个 .Net class,它使用 Marshal.AllocHGlobal
为 struct
分配非托管内存,然后使用 Marshal.FreeHGlobal
.
处理它
我知道 classes Microsoft.Win32.SafeHandles
提供了处理这个的包装器,但不清楚如何实例化它们(许多没有构造函数)——我应该写一个抽象基础 class 的具体实现,或者有什么方法可以在 extern
声明中使用它们?
子类化 SafeHandle
的主要问题是 Marshal.DestroyStructure
您需要结构的 Type
... 这让一切都变得更加复杂。
你不能使用泛型(因为它们与 pinvoke 不兼容)...所以你可以有多个 SafeHandle
子类(每个 Type
一个),或者一个 属性 在 SafeHandle
中使用您手动设置的结构类型...或者您可以使 SafeHandle
的构造函数接受要编组的结构并设置 Type
在 属性.
中
我正在使用最后两个 "options"(属性 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 class,它使用 Marshal.AllocHGlobal
为 struct
分配非托管内存,然后使用 Marshal.FreeHGlobal
.
我知道 classes Microsoft.Win32.SafeHandles
提供了处理这个的包装器,但不清楚如何实例化它们(许多没有构造函数)——我应该写一个抽象基础 class 的具体实现,或者有什么方法可以在 extern
声明中使用它们?
子类化 SafeHandle
的主要问题是 Marshal.DestroyStructure
您需要结构的 Type
... 这让一切都变得更加复杂。
你不能使用泛型(因为它们与 pinvoke 不兼容)...所以你可以有多个 SafeHandle
子类(每个 Type
一个),或者一个 属性 在 SafeHandle
中使用您手动设置的结构类型...或者您可以使 SafeHandle
的构造函数接受要编组的结构并设置 Type
在 属性.
我正在使用最后两个 "options"(属性 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
.