Beispiel #1
0
        public static T[] __FromPInvoke <T>(SafeArray data)
        {
            if (data.Size == 0)
            {
                return(new T[0]);
            }

            var type = typeof(T);

            T[] result;
            if (type.IsValueType)
            {
                // Array of structs or builtin types.
                var size = Marshal.SizeOf <T>();
                result = new T[data.Size / size];
                var handle = GCHandle.Alloc(result, GCHandleType.Pinned);
                Buffer.MemoryCopy((void *)data.Data, (void *)handle.AddrOfPinnedObject(), data.Size, data.Size);
                handle.Free();
            }
            else
            {
                // Array of pointers to objects
                var tFromPInvoke = type.GetMethod("__FromPInvoke", BindingFlags.NonPublic | BindingFlags.Static);
                var pointers     = (void **)data.Data;
                Debug.Assert(pointers != null);
                Debug.Assert(tFromPInvoke != null);
                var count = data.Size / IntPtr.Size;
                result = new T[count];
                for (int i = 0; i < count; i++)
                {
                    result[i] = (T)tFromPInvoke.Invoke(null, new object[] { new IntPtr(pointers[i]) });
                }
            }

            if (data.Owns)
            {
                MarshalTools.c_free(data.Data);
            }

            return(result);
        }
Beispiel #2
0
        public static SafeArray __ToPInvoke <T>(T[] data)
        {
            if (data == null)
            {
                return(new SafeArray());
            }

            var type   = typeof(T);
            var result = new SafeArray {
                Owns = true
            };

            if (type.IsValueType)
            {
                // Array of structs or builtin types.
                result.Size = data.Length * Marshal.SizeOf <T>();
                result.Data = MarshalTools.c_alloc(result.Size);
                var handle = GCHandle.Alloc(result, GCHandleType.Pinned);
                Buffer.MemoryCopy((void *)handle.AddrOfPinnedObject(), (void *)result.Data, result.Size, result.Size);
                handle.Free();
            }
            else
            {
                // Array of pointers to objects
                result.Size = data.Length * IntPtr.Size;
                result.Data = MarshalTools.c_alloc(result.Size);
                var tToPInvoke = type.GetMethod("__ToPInvoke", BindingFlags.NonPublic | BindingFlags.Static);
                var pointers   = (void **)result.Size;
                Debug.Assert(tToPInvoke != null);
                Debug.Assert(pointers != null);
                for (var i = 0; i < data.Length; i++)
                {
                    pointers[i] = ((IntPtr)tToPInvoke.Invoke(null, new object[] { data[i] })).ToPointer();
                }
            }

            return(result);
        }