有没有办法将结构(可能存储在 TypedReference 中)编组到非托管内存而不实际装箱?结构的类型在运行时是未知的,因此我不能使用StructureToPtr(.NET 4.5.1)的泛型重载。我可以获得 StructureToPtr 重载的MethodInfo,但似乎没有办法调用它来传递泛型引用或 TypedReference 。
编辑:通用 StructureToPtr 仍然会对结构进行包装,因此尝试调用它是没用的。
答案 0 :(得分:2)
我终于找到了答案,SafeBuffer
课程。它包含我想要的内容 - 使用TypedReference
和泛型参数的编组方法结构。所以,制作包装器真的很简单:
public static unsafe class InteropTools
{
private static readonly Type SafeBufferType = typeof(SafeBuffer);
public delegate void PtrToStructureNativeDelegate(byte* ptr, TypedReference structure, uint sizeofT);
public delegate void StructureToPtrNativeDelegate(TypedReference structure, byte* ptr, uint sizeofT);
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static;
private static readonly MethodInfo PtrToStructureNativeMethod = SafeBufferType.GetMethod("PtrToStructureNative", flags);
private static readonly MethodInfo StructureToPtrNativeMethod = SafeBufferType.GetMethod("StructureToPtrNative", flags);
public static readonly PtrToStructureNativeDelegate PtrToStructureNative = (PtrToStructureNativeDelegate)Delegate.CreateDelegate(typeof(PtrToStructureNativeDelegate), PtrToStructureNativeMethod);
public static readonly StructureToPtrNativeDelegate StructureToPtrNative = (StructureToPtrNativeDelegate)Delegate.CreateDelegate(typeof(StructureToPtrNativeDelegate), StructureToPtrNativeMethod);
private static readonly Func<Type,bool,int> SizeOfHelper_f = (Func<Type,bool,int>)Delegate.CreateDelegate(typeof(Func<Type,bool,int>), typeof(Marshal).GetMethod("SizeOfHelper", flags));
public static void StructureToPtrDirect(TypedReference structure, IntPtr ptr, int size)
{
StructureToPtrNative(structure, (byte*)ptr, unchecked((uint)size));
}
public static void StructureToPtrDirect(TypedReference structure, IntPtr ptr)
{
StructureToPtrDirect(structure, ptr, SizeOf(__reftype(structure)));
}
public static void PtrToStructureDirect(IntPtr ptr, TypedReference structure, int size)
{
PtrToStructureNative((byte*)ptr, structure, unchecked((uint)size));
}
public static void PtrToStructureDirect(IntPtr ptr, TypedReference structure)
{
PtrToStructureDirect(ptr, structure, SizeOf(__reftype(structure)));
}
public static void StructureToPtr<T>(ref T structure, IntPtr ptr)
{
StructureToPtrDirect(__makeref(structure), ptr);
}
public static void PtrToStructure<T>(IntPtr ptr, out T structure)
{
structure = default(T);
PtrToStructureDirect(ptr, __makeref(structure));
}
public static T PtrToStructure<T>(IntPtr ptr)
{
T obj;
PtrToStructure(ptr, out obj);
return obj;
}
public static int SizeOf<T>(T structure)
{
return SizeOf<T>();
}
public static int SizeOf<T>()
{
return SizeOf(typeof(T));
}
public static int SizeOf(Type t)
{
return SizeOfHelper_f(t, true);
}
}
<强>用法强>
Guid g = Guid.NewGuid();
int size = InteropTools.SizeOf(g);
IntPtr mem = Marshal.AllocHGlobal(size);
InteropTools.StructureToPtr(ref g, mem);
Guid g2 = InteropTools.PtrToStructure<Guid>(mem);
现在,它实际上比Marshal
类中的非泛型对象获取方法有什么优势吗?似乎StructureToPtr
花费的时间减少了大约80%,而PtrToStructure
可以减少近95%的时间。此外,这些方法可以正确处理可空类型。