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();
                    }
                }
            }
Beispiel #2
0
        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);
            }
        }