예제 #1
0
        public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
        {
            if (structure == null)
            {
                throw new ArgumentNullException(nameof(structure));
            }

            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (fDeleteOld)
            {
                DestroyStructure(ptr, structure.GetType());
            }

            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericObject, nameof(structure));
            }

            IntPtr marshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructMarshalStub(structureTypeHandle, out marshalStub))
                {
                    marshalStub = IntPtr.Zero;
                }
            }
            else
            {
                marshalStub = RuntimeAugments.InteropCallbacks.GetStructMarshalStub(structureTypeHandle);
            }

            if (marshalStub != IntPtr.Zero)
            {
                if (structureTypeHandle.IsValueType())
                {
                    ((delegate * < ref byte, ref byte, void >)marshalStub)(ref structure.GetRawData(), ref *(byte *)ptr);
                }
                else
                {
                    ((delegate * < object, ref byte, void >)marshalStub)(structure, ref *(byte *)ptr);
                }
            }
            else
            {
                nuint size = (nuint)RuntimeAugments.InteropCallbacks.GetStructUnsafeStructSize(structureTypeHandle);

                Buffer.Memmove(ref *(byte *)ptr, ref structure.GetRawData(), size);
            }
        }
예제 #2
0
        private static uint SizeOf <T>() where T : struct
        {
            RuntimeTypeHandle structureTypeHandle = typeof(T).TypeHandle;

            if (!structureTypeHandle.IsBlittable())
            {
                throw new ArgumentException(SR.Argument_NeedStructWithNoRefs);
            }

            return((uint)Unsafe.SizeOf <T>());
        }
예제 #3
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            // Boxed struct start at offset 1 (EEType* at offset 0) while class start at offset 0
            int offset = structureTypeHandle.IsValueType() ? 1 : 0;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            if (unmarshalStub != IntPtr.Zero)
            {
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    CalliIntrinsics.Call <int>(
                        unmarshalStub,
                        (void *)ptr,                                        // unsafe (no need to adjust as it is always struct)
                        ((void *)((IntPtr *)unboxedStructPtr + offset))     // safe (need to adjust offset as it could be class)
                        );
                });
            }
            else
            {
                int structSize = Marshal.SizeOf(structure);
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    InteropExtensions.Memcpy(
                        (IntPtr)((IntPtr *)unboxedStructPtr + offset),      // safe (need to adjust offset as it could be class)
                        ptr,                                                // unsafe (no need to adjust as it is always struct)
                        structSize
                        );
                });
            }
        }
예제 #4
0
        public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)
        {
            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (structuretype == null)
            {
                throw new ArgumentNullException(nameof(structuretype));
            }

            RuntimeTypeHandle structureTypeHandle = structuretype.TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericType, "t");
            }

            if (structureTypeHandle.IsEnum() ||
                structureTypeHandle.IsInterface() ||
                InteropExtensions.AreTypesAssignable(typeof(Delegate).TypeHandle, structureTypeHandle))
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }

            if (structureTypeHandle.IsBlittable())
            {
                // ok to call with blittable structure, but no work to do in this case.
                return;
            }

            IntPtr destroyStructureStub = RuntimeAugments.InteropCallbacks.GetDestroyStructureStub(structureTypeHandle, out bool hasInvalidLayout);

            if (hasInvalidLayout)
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }
            // DestroyStructureStub == IntPtr.Zero means its fields don't need to be destroied
            if (destroyStructureStub != IntPtr.Zero)
            {
                CalliIntrinsics.Call <int>(
                    destroyStructureStub,
                    (void *)ptr                                     // unsafe (no need to adjust as it is always struct)
                    );
            }
        }
예제 #5
0
        public override int GetStructUnsafeStructSize(RuntimeTypeHandle structureTypeHandle)
        {
            if (TryGetStructUnsafeStructSize(structureTypeHandle, out int size))
            {
                return(size);
            }

            // IsBlittable() checks whether the type contains GC references. It is approximate check with false positives.
            // This fallback path will return incorrect answer for types that do not contain GC references, but that are
            // not actually blittable; e.g. for types with bool fields.
            if (structureTypeHandle.IsBlittable() && structureTypeHandle.IsValueType())
            {
                return(structureTypeHandle.GetValueTypeSize());
            }

            throw new MissingInteropDataException(SR.StructMarshalling_MissingInteropData, Type.GetTypeFromHandle(structureTypeHandle));
        }
예제 #6
0
파일: SafeBuffer.cs 프로젝트: wffy/corert
        private static int SizeOf(Type t)
        {
            Debug.Assert(t != null, "t");

            if (t.TypeHandle.IsGenericType())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericType, "t");
            }

            RuntimeTypeHandle typeHandle = t.TypeHandle;

            if (!(typeHandle.IsBlittable() && typeHandle.IsValueType()))
            {
                throw new ArgumentException(SR.Argument_NeedStructWithNoRefs);
            }

            return(typeHandle.GetValueTypeSize());
        }
예제 #7
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            if (unmarshalStub != IntPtr.Zero)
            {
                if (structureTypeHandle.IsValueType())
                {
                    CalliIntrinsics.Call(
                        unmarshalStub,
                        ref *(byte *)ptr,
                        ref structure.GetRawData());
                }
                else
                {
                    CalliIntrinsics.Call(
                        unmarshalStub,
                        ref *(byte *)ptr,
                        structure);
                }
            }
            else
            {
                nuint size = (nuint)RuntimeAugments.InteropCallbacks.GetStructUnsafeStructSize(structureTypeHandle);
                fixed(byte *pDest = &structure.GetRawData())
                {
                    Buffer.Memmove(pDest, (byte *)ptr, size);
                }
            }
        }
예제 #8
0
        public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)
        {
            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (structuretype == null)
            {
                throw new ArgumentNullException(nameof(structuretype));
            }

            RuntimeTypeHandle structureTypeHandle = structuretype.TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structuretype));
            }

            if (structureTypeHandle.IsEnum() ||
                structureTypeHandle.IsInterface() ||
                InteropExtensions.AreTypesAssignable(typeof(Delegate).TypeHandle, structureTypeHandle))
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }

            if (structureTypeHandle.IsBlittable())
            {
                // ok to call with blittable structure, but no work to do in this case.
                return;
            }

            IntPtr destroyStructureStub = RuntimeInteropData.GetDestroyStructureStub(structureTypeHandle, out bool hasInvalidLayout);

            if (hasInvalidLayout)
            {
                throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structureTypeHandle.LastResortToString));
            }
            // DestroyStructureStub == IntPtr.Zero means its fields don't need to be destroyed
            if (destroyStructureStub != IntPtr.Zero)
            {
                ((delegate * < ref byte, void >)destroyStructureStub)(ref *(byte *)ptr);
            }
        }
예제 #9
0
파일: SafeBuffer.cs 프로젝트: wffy/corert
        internal static void GenericStructureToPtr <T>(ref T structure, byte *ptr, uint sizeofT) where T : struct
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            if (!structureTypeHandle.IsBlittable())
            {
                throw new ArgumentException(SR.Argument_NeedStructWithNoRefs);
            }

            InteropExtensions.PinObjectAndCall((Object)structure,
                                               unboxedStructPtr =>
            {
                InteropExtensions.Memcpy(
                    (IntPtr)ptr,                                  // unsafe (no need to adjust as it is always struct)
                    (IntPtr)((IntPtr *)unboxedStructPtr + 1),     // safe (need to adjust offset as boxed structure start at offset 1)
                    (int)sizeofT
                    );
            });
        }
예제 #10
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            // Boxed struct start at offset 1 (EEType* at offset 0) while class start at offset 0
            nuint offset = structureTypeHandle.IsValueType() ? (nuint)sizeof(IntPtr) : 0;

            IntPtr unmarshalStub;
            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            ref byte dest = ref Unsafe.AddByteOffset(ref Unsafe.As<IntPtr, byte>(ref structure.m_pEEType), offset);
예제 #11
0
파일: SafeBuffer.cs 프로젝트: wffy/corert
        internal static void GenericPtrToStructure <T>(byte *ptr, out T structure, uint sizeofT) where T : struct
        {
            RuntimeTypeHandle structureTypeHandle = typeof(T).TypeHandle;

            if (!structureTypeHandle.IsBlittable())
            {
                throw new ArgumentException(SR.Argument_NeedStructWithNoRefs);
            }

            Object boxedStruct = new T();

            InteropExtensions.PinObjectAndCall(boxedStruct,
                                               unboxedStructPtr =>
            {
                InteropExtensions.Memcpy(
                    (IntPtr)((IntPtr *)unboxedStructPtr + 1),     // safe (need to adjust offset as boxed structure start at offset 1)
                    (IntPtr)ptr,                                  // unsafe (no need to adjust as it is always struct)
                    (int)sizeofT
                    );
            });

            structure = (T)boxedStruct;
        }
예제 #12
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeAugments.InteropCallbacks.GetStructUnmarshalStub(structureTypeHandle);
            }

            if (unmarshalStub != IntPtr.Zero)
            {
                if (structureTypeHandle.IsValueType())
                {
                    ((delegate * < ref byte, ref byte, void >)unmarshalStub)(ref *(byte *)ptr, ref structure.GetRawData());
                }
                else
                {
                    ((delegate * < ref byte, object, void >)unmarshalStub)(ref *(byte *)ptr, structure);
                }
            }
            else
            {
                nuint size = (nuint)RuntimeAugments.InteropCallbacks.GetStructUnsafeStructSize(structureTypeHandle);

                Buffer.Memmove(ref structure.GetRawData(), ref *(byte *)ptr, size);
            }
        }
예제 #13
0
        public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
        {
            if (structure == null)
            {
                throw new ArgumentNullException(nameof(structure));
            }

            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(ptr));
            }

            if (fDeleteOld)
            {
                DestroyStructure(ptr, structure.GetType());
            }

            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(nameof(structure), SR.Argument_NeedNonGenericObject);
            }

            // Boxed struct start at offset 1 (EEType* at offset 0) while class start at offset 0
            int offset = structureTypeHandle.IsValueType() ? 1 : 0;

            IntPtr marshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeAugments.InteropCallbacks.TryGetStructMarshalStub(structureTypeHandle, out marshalStub))
                {
                    marshalStub = IntPtr.Zero;
                }
            }
            else
            {
                marshalStub = RuntimeAugments.InteropCallbacks.GetStructMarshalStub(structureTypeHandle);
            }

            if (marshalStub != IntPtr.Zero)
            {
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    CalliIntrinsics.Call <int>(
                        marshalStub,
                        ((void *)((IntPtr *)unboxedStructPtr + offset)),    // safe (need to adjust offset as it could be class)
                        (void *)ptr                                         // unsafe (no need to adjust as it is always struct)
                        );
                });
            }
            else
            {
                int structSize = Marshal.SizeOf(structure);
                InteropExtensions.PinObjectAndCall(structure,
                                                   unboxedStructPtr =>
                {
                    InteropExtensions.Memcpy(
                        ptr,                                                // unsafe (no need to adjust as it is always struct)
                        (IntPtr)((IntPtr *)unboxedStructPtr + offset),      // safe (need to adjust offset as it could be class)
                        structSize
                        );
                });
            }
        }