public static T[] ToArray <T>(IntPtr ptr, int size) where T : struct
        {
            if (ptr == IntPtr.Zero)
            {
                return(null);
            }
            if (size == 0)
            {
                return(new T[0]);
            }

            MarshalingDescriptor marshalDesc;
            Marshaler            marshaller = CreateNativeMarshaller(
                typeof(T[]),
                null,
                size,
                null,
                false,
                -1,
                out marshalDesc);

            int     arraySize = marshaller.GetSize(marshalDesc, null);
            IRegion region    = marshaller.MakeRegion(ptr, arraySize);

            return((T[])marshaller.UnmarshalFrom(marshalDesc, region));
        }
        /// <summary>
        /// Marshal a managed structure to unmanaged memory.
        /// </summary>
        /// <typeparam name="T">Type of struct.</typeparam>
        /// <param name="t">A structure to marshal.</param>
        /// <param name="switchValue">Switch attribute value if presents.</param>
        /// <param name="sizeValue">Size attribute value if presents.</param>
        /// <param name="lengthValue">Length attribute value if presents.</param>
        /// <returns>Marshalled unmanaged memory.</returns>
        public static SafeIntPtr ToIntPtr <T>(
            T t,
            object switchValue,
            object sizeValue,
            object lengthValue) where T : struct
        {
            MarshalingDescriptor marshalDesc;
            Marshaler            marshaller = CreateNativeMarshaller(
                typeof(T),
                switchValue,
                sizeValue,
                lengthValue,
                false,
                -1,
                out marshalDesc);

            int    size = marshaller.GetSize(marshalDesc, t);
            IntPtr ptr  = Marshal.AllocHGlobal(size);

            IRegion region = marshaller.MakeRegion(ptr, size);

            marshaller.MarshalInto(marshalDesc, region, t);

            return(new TypeMarshalSafeIntPtr(marshaller, ptr));
        }
        /// <summary>
        /// Marshal a managed array to unmanaged memory.
        /// </summary>
        /// <typeparam name="T">Type of elements in the array.</typeparam>
        /// <param name="array">An array to marshal.</param>
        /// <returns>Marshalled unmanaged memory.</returns>
        public static SafeIntPtr ToIntPtr <T>(T[] array) where T : struct
        {
            if (array == null)
            {
                return(IntPtr.Zero);
            }

            MarshalingDescriptor marshalDesc;
            Marshaler            marshaller = CreateNativeMarshaller(
                typeof(T[]),
                null,
                array.Length,
                null,
                false,
                -1,
                out marshalDesc);

            int    size = marshaller.GetSize(marshalDesc, array);
            IntPtr ptr  = Marshal.AllocHGlobal(size);

            IRegion region = marshaller.MakeRegion(ptr, size);

            marshaller.MarshalInto(marshalDesc, region, array);

            return(new TypeMarshalSafeIntPtr(marshaller, ptr));
        }
        public static T ToStruct <T>(
            IntPtr ptr,
            object switchValue,
            object sizeValue,
            object lengthValue,
            bool force32Bit = false,
            int align       = -1) where T : struct
        {
            MarshalingDescriptor marshalDesc;
            Marshaler            marshaller = CreateNativeMarshaller(
                typeof(T),
                switchValue,
                sizeValue,
                lengthValue,
                force32Bit,
                align,
                out marshalDesc);

            int     size   = marshaller.GetSize(marshalDesc, null);
            IRegion region = marshaller.MakeRegion(ptr, size);

            return((T)marshaller.UnmarshalFrom(marshalDesc, region));
        }
            internal void AllocateMemoryRegion(Marshaler marshaler, object value)
            {
                if (marshallingRegion != null)
                {
                    marshaler.MarkMemoryForDispose(this.marshallingRegion.NativeMemory);
                    this.marshallingRegion = null;
                }

                if (context.Type != typeof(void))
                {
                    int s = marshaler.GetSize(context, value);
                    IntPtr p = Marshal.AllocHGlobal(s);
                    this.marshallingRegion = marshaler.MakeRegion(p, s);
                }
                else
                    this.marshallingRegion = null;
            }