Example #1
0
        /// <summary>
        /// This thunk creates a delegate from a native function pointer
        /// by first creating a PInvokeDelegateWrapper from the function pointer
        /// and then creating the delegate from the Invoke method of the wrapper
        ///
        /// Generated IL:
        ///     ldarg   0
        ///     newobj PInvokeDelegateWrapper.ctor
        ///     dup
        ///     ldvirtftn PInvokeDelegateWrapper.Invoke
        ///     newobj DelegateType.ctor
        ///     ret
        ///
        /// Equivalent C#
        ///     return new DelegateType(new PInvokeDelegateWrapper(functionPointer).Invoke)
        /// </summary>
        public override MethodIL EmitIL()
        {
            var          emitter    = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            codeStream.EmitLdArg(0);

            codeStream.Emit(ILOpcode.newobj, emitter.NewToken(
                                _interopStateManager.GetPInvokeDelegateWrapper(DelegateType)
                                .GetPInvokeDelegateWrapperMethod(PInvokeDelegateWrapperMethodKind.Constructor)));

            codeStream.Emit(ILOpcode.dup);

            codeStream.Emit(ILOpcode.ldvirtftn, emitter.NewToken(
                                _interopStateManager.GetPInvokeDelegateWrapper(DelegateType)
                                .GetPInvokeDelegateWrapperMethod(PInvokeDelegateWrapperMethodKind.Invoke)));

            codeStream.Emit(ILOpcode.newobj, emitter.NewToken(
                                _delegateType.GetMethod(".ctor",
                                                        new MethodSignature(MethodSignatureFlags.None,
                                                                            genericParameterCount: 0,
                                                                            returnType: Context.GetWellKnownType(WellKnownType.Void),
                                                                            parameters: new TypeDesc[] { Context.GetWellKnownType(WellKnownType.Object),
                                                                                                         Context.GetWellKnownType(WellKnownType.IntPtr) }
                                                                            ))));

            codeStream.Emit(ILOpcode.ret);

            return(emitter.Link(this));
        }