我有一个.Net类,使用struct
为Marshal.AllocHGlobal
分配非托管内存,然后使用Marshal.FreeHGlobal
处理它。
我理解类Microsoft.Win32.SafeHandles
提供了处理这个的包装器,但是不清楚如何实例化它们(很多都没有构造函数) - 我应该编写抽象基类的特定实现或者有没有办法在extern
声明中使用它们?
答案 0 :(得分:6)
子类化SafeHandle
的主要问题是,Marshal.DestroyStructure
需要结构的Type
...这会使一切变得更加复杂。
你不能使用泛型(因为它们与pinvoke不兼容)...所以你可以拥有多个SafeHandle
子类(每个Type
一个),或SafeHandle
内的属性{1}}使用您手动设置的结构类型...或者您可以使SafeHandle
的构造函数接受要封送的结构并在属性中设置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
。