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); }
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); } }
/// <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)); }
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); } }
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))); }
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); } }
internal static int SizeOfHelper(Type t, bool throwIfNotMarshalable) { Debug.Assert(throwIfNotMarshalable); return(RuntimeInteropData.GetStructUnsafeStructSize(t.TypeHandle)); }