public IntPtr ContextData; // ThunkContextData pointer which will be stored in the context slot of the thunk public PInvokeDelegateThunk(Delegate del) { Thunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap); Debug.Assert(Thunk != IntPtr.Zero); if (Thunk == IntPtr.Zero) { // We've either run out of memory, or failed to allocate a new thunk due to some other bug. Now we should fail fast Environment.FailFast("Insufficient number of thunks."); } else { // // Allocate unmanaged memory for GCHandle of delegate and function pointer of open static delegate // We will store this pointer on the context slot of thunk data // ContextData = AllocHGlobal(2 * IntPtr.Size); unsafe { ThunkContextData *thunkData = (ThunkContextData *)ContextData; // allocate a weak GChandle for the delegate thunkData->Handle = GCHandle.Alloc(del, GCHandleType.Weak); // if it is an open static delegate get the function pointer thunkData->FunctionPtr = del.GetRawFunctionPointerForOpenStaticDelegate(); } } }
private static IntPtr AllocateThunk(Delegate del) { //TODO: cache del->thunk here if (s_thunkPoolHeap == null) { s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress()); Debug.Assert(s_thunkPoolHeap != null); } IntPtr pThunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap); Debug.Assert(pThunk != IntPtr.Zero); if (pThunk == IntPtr.Zero) { // We've either run out of memory, or failed to allocate a new thunk due to some other bug. Now we should fail fast Environment.FailFast("Insufficient number of thunks."); return(IntPtr.Zero); } else { McgPInvokeDelegateData pinvokeDelegateData; if (!RuntimeAugments.InteropCallbacks.TryGetMarshallerDataForDelegate(del.GetTypeHandle(), out pinvokeDelegateData)) { Environment.FailFast("Couldn't find marshalling stubs for delegate."); } IntPtr pContext; unsafe { // // Allocate unmanaged memory for GCHandle of delegate and function pointer of open static delegate // We will store this pointer on the context slot of thunk data // pContext = (IntPtr)CoTaskMemAllocAndZeroMemory((System.IntPtr)(2 * (IntPtr.Size))); ThunkContextData *thunkData = (ThunkContextData *)pContext; (*thunkData).Handle = GCHandle.Alloc(del, GCHandleType.Weak); (*thunkData).FunctionPtr = del.GetRawFunctionPointerForOpenStaticDelegate(); } // // For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly // IntPtr pTarget = del.GetRawFunctionPointerForOpenStaticDelegate() == IntPtr.Zero ? pinvokeDelegateData.ReverseStub : pinvokeDelegateData.ReverseOpenStaticDelegateStub; RuntimeAugments.SetThunkData(s_thunkPoolHeap, pThunk, pContext, pTarget); return(pThunk); } }