Marshal.StructureToPtr无拳 [英] Marshal.StructureToPtr without boxing

查看:574
本文介绍了Marshal.StructureToPtr无拳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法编组结构(可能存储在一个的 TypedReference 的),以没有实际拳击它非托管内存?该类型结构在运行时没有出名的,所以我不能使用StructureToPtr(.NET 4.5.1)的泛型重载。我能得到的 StructureToPtr 的过载,但似乎没有成为一个方式来调用它通过一个通用的参考或 TypedReference

Is there a way to marshal a structure (possibly stored in a TypedReference) to unmanaged memory without actually boxing it? The type of the structure isn't known at runtime, so I can't use the generic overload of StructureToPtr (.NET 4.5.1). I can get a MethodInfo of the StructureToPtr overload, but there doesn't seem to be a way to invoke it passing a generic reference or a TypedReference.

编辑:通用的 StructureToPtr 的还箱结构,使试图调用它是无用的。

The generic StructureToPtr still boxes the structure, so trying to invoke it is useless.

推荐答案

我终于找到了答案,在的 SafeBuffer 类。它包含正是我想要的 - 结构编组方法同时使用 TypedReference 和通用参数。所以,这是非常简单的,然后做一个包装:

I've finally found the answer, the SafeBuffer class. It contains exactly what I wanted - structure with marshalling methods using both TypedReference and generic parameters. So, it's really simple then to make a wrapper:

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);

现在,它实际上已经超过了<$非通用对象回吐的方法有什么优势C $ C>元帅类?看来 StructureToPtr 占用较少约80%的时间,而 PtrToStructure 可以减少近95%的时间。此外,这些方法都可以正确处理可空类型。

Now, does it actually have any advantages over the non-generic object-taking methods in the Marshal class? It seems the StructureToPtr takes about 80 % less time, and PtrToStructure can take almost 95 % less time. Also, these methods can handle nullable types correctly.

这篇关于Marshal.StructureToPtr无拳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆