Пример #1
0
        private static PInvokeDelegateThunk AllocateThunk(Delegate del)
        {
            if (s_thunkPoolHeap == null)
            {
                // TODO: Free s_thunkPoolHeap if the thread lose the race
                Interlocked.CompareExchange(
                    ref s_thunkPoolHeap,
                    RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()),
                    null
                    );
                Debug.Assert(s_thunkPoolHeap != null);
            }

            var delegateThunk = new PInvokeDelegateThunk(del);

            //
            //  For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
            //
            bool openStaticDelegate = del.GetRawFunctionPointerForOpenStaticDelegate() != IntPtr.Zero;

            IntPtr pTarget = RuntimeInteropData.GetDelegateMarshallingStub(del.GetTypeHandle(), openStaticDelegate);

            Debug.Assert(pTarget != IntPtr.Zero);

            RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget);

            return(delegateThunk);
        }
Пример #2
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 (!RuntimeInteropData.TryGetStructMarshalStub(structureTypeHandle, out marshalStub))
                {
                    marshalStub = IntPtr.Zero;
                }
            }
            else
            {
                marshalStub = RuntimeInteropData.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)RuntimeInteropData.GetStructUnsafeStructSize(structureTypeHandle);

                Buffer.Memmove(ref *(byte *)ptr, ref structure.GetRawData(), size);
            }
        }
Пример #3
0
        /// <summary>
        /// Retrieve the corresponding P/invoke instance from the stub
        /// </summary>
        public static unsafe Delegate?GetDelegateForFunctionPointer(IntPtr ptr, RuntimeTypeHandle delegateType)
        {
            if (ptr == IntPtr.Zero)
            {
                return(null);
            }
            //
            // First try to see if this is one of the thunks we've allocated when we marshal a managed
            // delegate to native code
            // s_thunkPoolHeap will be null if there isn't any managed delegate to native
            //
            IntPtr pContext;
            IntPtr pTarget;

            if (s_thunkPoolHeap != null && RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, ptr, out pContext, out pTarget))
            {
                GCHandle handle;
                unsafe
                {
                    // Pull out Handle from context
                    handle = ((ThunkContextData *)pContext)->Handle;
                }
                Delegate target = Unsafe.As <Delegate>(handle.Target);

                //
                // The delegate might already been garbage collected
                // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive
                // until they are done with the native function pointer
                //
                if (target == null)
                {
                    Environment.FailFast(SR.Delegate_GarbageCollected);
                }

                return(target);
            }

            //
            // Otherwise, the stub must be a pure native function pointer
            // We need to create the delegate that points to the invoke method of a
            // NativeFunctionPointerWrapper derived class
            //
            IntPtr pDelegateCreationStub = RuntimeInteropData.GetForwardDelegateCreationStub(delegateType);

            Debug.Assert(pDelegateCreationStub != IntPtr.Zero);

            return(((delegate * < IntPtr, Delegate >)pDelegateCreationStub)(ptr));
        }
Пример #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, 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);
            }
        }
Пример #5
0
        public static IntPtr OffsetOf(Type t, string fieldName)
        {
            if (t == null)
            {
                throw new ArgumentNullException(nameof(t));
            }

            if (string.IsNullOrEmpty(fieldName))
            {
                throw new ArgumentNullException(nameof(fieldName));
            }

            if (t.TypeHandle.IsGenericTypeDefinition())
            {
                throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
            }

            return(new IntPtr(RuntimeInteropData.GetStructFieldOffset(t.TypeHandle, fieldName)));
        }
Пример #6
0
        internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
        {
            RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;

            IntPtr unmarshalStub;

            if (structureTypeHandle.IsBlittable())
            {
                if (!RuntimeInteropData.TryGetStructUnmarshalStub(structureTypeHandle, out unmarshalStub))
                {
                    unmarshalStub = IntPtr.Zero;
                }
            }
            else
            {
                unmarshalStub = RuntimeInteropData.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)RuntimeInteropData.GetStructUnsafeStructSize(structureTypeHandle);

                Buffer.Memmove(ref structure.GetRawData(), ref *(byte *)ptr, size);
            }
        }
Пример #7
0
 internal static int SizeOfHelper(Type t, bool throwIfNotMarshalable)
 {
     Debug.Assert(throwIfNotMarshalable);
     return(RuntimeInteropData.GetStructUnsafeStructSize(t.TypeHandle));
 }