【问题标题】:JIT Compiler error - Invalid Program Exception using Reflection.EmitJIT 编译器错误 - 使用 Reflection.Emit 的程序异常无效
【发布时间】:2010-04-07 18:34:50
【问题描述】:

有人可以向我解释为什么以下内容适用于第一个测试但会引发 InvalidProgramException 用于第二个测试?我被难住了。

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace DMTest { class Program { static void Main(string[] args) { Test.NewResultWithParam(); Console.WriteLine("Press any key to continue"); Console.ReadLine(); Test.NewResult(); Console.WriteLine("Press any key to exit"); Console.ReadLine(); } }

public static class Test { public static void NewResult() { var f = typeof(Result).New<Result>(); var result = f.Invoke(); } public static void NewResultWithParam() { var f = typeof(Result).New<Param, Result>(); var result = f.Invoke(new Param("Parameter Executed")); result.Build(); } } public static class DynamicFunctions { public static Func<R> New<R>(this Type type) { if (!typeof(R).IsAssignableFrom(type)) { throw new ArgumentException(); } var dm = BuildNewMethod(type, Type.EmptyTypes); return (Func<R>)dm.CreateDelegate(typeof(Func<R>)); } public static Func<T, R> New<T, R>(this Type type) { if (!typeof(R).IsAssignableFrom(type)) { throw new ArgumentException(); } var dm = BuildNewMethod(type, new Type[] { typeof(T) }); return (Func<T, R>)dm.CreateDelegate(typeof(Func<T, R>)); } private static DynamicMethod BuildNewMethod(Type newObjType, Type[] parameterTypes) { var dm = new DynamicMethod("New_" + newObjType.FullName, newObjType, parameterTypes, newObjType); var info = newObjType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, parameterTypes, new ParameterModifier[0]); ILGenerator il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, info); il.Emit(OpCodes.Ret); return dm; } } public class Result { private Param _param; private Result() { Console.WriteLine("Parameterless constructor called"); } private Result(Param param) { Console.WriteLine("Parametered constructor called"); _param = param; } public void Build() { _param.Execute(); } } public class Param { private string _s; public Param(string s) { _s = s; } public void Execute() { Console.WriteLine(_s); } }

}

【问题讨论】:

    标签: c# reflection.emit dynamicmethod


    【解决方案1】:
    il.Emit(OpCodes.Ldarg_0); // <-- problem here
    

    由于您的动态方法在New&lt;T&gt; 版本中没有参数,因此您不能使用Ldarg_0。此外,Newobj 将期望零参数,因此您的堆栈是不平衡的。

    【讨论】:

    • 已修复。谢谢你。我认为这是我缺少的一些简单的东西。
    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2012-11-10
    相关资源
    最近更新 更多