public void TestDynamicMethodEmitCalliNonBlittable() { string input = "Test string!", result = "!gnirts tseT"; Type returnType = typeof(string); var dynamicMethod = new DynamicMethod("F", returnType, new Type[] { typeof(IntPtr), typeof(string) }); ILGenerator il = dynamicMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, returnType, new Type[] { typeof(string) }); il.Emit(OpCodes.Ret); var del = new StringReverseCdecl(StringReverse); IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(del); object resultValue = dynamicMethod .Invoke(null, new object[] { funcPtr, input }); GC.KeepAlive(del); Assert.IsType(returnType, resultValue); Assert.Equal(result, resultValue); }
public void TestEmitCalliNonBlittable() { string input = "Test string!", result = "!gnirts tseT"; ModuleBuilder moduleBuilder = Helpers.DynamicModule(); TypeBuilder typeBuilder = moduleBuilder.DefineType("T", TypeAttributes.Public); Type returnType = typeof(string); MethodBuilder methodBuilder = typeBuilder.DefineMethod("F", MethodAttributes.Public | MethodAttributes.Static, returnType, new Type[] { typeof(IntPtr), typeof(string) }); methodBuilder.SetImplementationFlags(MethodImplAttributes.NoInlining); ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, returnType, new Type[] { typeof(string) }); il.Emit(OpCodes.Ret); Type dynamicType = typeBuilder.CreateType(); var del = new StringReverseCdecl(StringReverse); IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(del); object resultValue = dynamicType .GetMethod("F", BindingFlags.Public | BindingFlags.Static) .Invoke(null, new object[] { funcPtr, input }); GC.KeepAlive(del); Assert.IsType(returnType, resultValue); Assert.Equal(result, resultValue); }