Kei*_*ith 2 .net winapi marshalling
我有一个.Net类,为struct使用分配非托管内存Marshal.AllocHGlobal,然后使用它来处理它Marshal.FreeHGlobal.
我理解这些类Microsoft.Win32.SafeHandles提供了处理这个的包装器,但是不清楚如何实例化它们(很多都没有构造函数) - 我应该编写抽象基类的特定实现还是有一些方法来使用它们在extern声明中?
子类化的主要问题SafeHandle是Marshal.DestroyStructure你需要Type结构...这使得一切都更复杂.
你不能使用泛型(因为它们与pinvoke不兼容)...所以你可以有多SafeHandle个子类(每个子类一个Type),或者SafeHandle你手动设置的结构类型中的属性......或者你可以使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;
}
}
Run Code Online (Sandbox Code Playgroud)
你应该使用的构造函数是用结构编组的构造函数Marshal.StructureToPtr.它的优点是它可以保存结构的类型,以便以后可以使用它Marshal.DestroyStructure.