Esempio n. 1
0
        public static unsafe IDisposable ChangeArrayType(Array array, Int32 oldElementSize, out void *pointer)
        {
            if (array.Length < 1)
            {
                throw new NotSupportedException();
            }

            SafeGCHandle handle = new SafeGCHandle(array, GCHandleType.Pinned);

            try
            {
                pointer = handle.AddrOfPinnedObject().ToPointer();
                UIntPtr *arrayPointer = (UIntPtr *)pointer;
                UIntPtr  arrayLength  = *(arrayPointer - 1);
                UIntPtr  arrayType    = *(arrayPointer - 2);
                UInt64   arraySize    = ((UInt64)arrayLength * (UInt64)oldElementSize);

                if (arraySize % (UInt64)UnsafeSize != 0)
                {
                    throw new InvalidCastException();
                }

                try
                {
                    *(arrayPointer - 1) = new UIntPtr(arraySize / (UInt64)UnsafeSize);
                    *(arrayPointer - 2) = ArrayTypePointer;

                    return(new DisposableAction(() =>
                    {
                        *(arrayPointer - 1) = arrayLength;
                        *(arrayPointer - 2) = arrayType;
                        handle.Dispose();
                    }));
                }
                catch
                {
                    *(arrayPointer - 1) = arrayLength;
                    *(arrayPointer - 2) = arrayType;
                    throw;
                }
            }
            catch
            {
                handle.Dispose();
                throw;
            }
        }
Esempio n. 2
0
 private static unsafe UIntPtr GetArrayTypePointer()
 {
     T[] result = new T[1];
     using (SafeGCHandle handle = new SafeGCHandle(result, GCHandleType.Pinned))
         return(*(((UIntPtr *)handle.AddrOfPinnedObject().ToPointer()) - 2));
 }