生成动态代码的问题

时间:2010-05-15 18:05:03

标签: c# .net reflection.emit il

此代码gif异常:调用异常,请帮助,我不知道发生了什么,我认为是Add的一些事情,因为当我推入堆栈的时候他工作,当我推lvalue它没有'工作,谢谢

static void Main(string[] args)
    {
        AppDomain dominioAplicacion = System.Threading.Thread.GetDomain();
        AssemblyName nombre_Del_Ensamblado = new AssemblyName("ASS");
        AssemblyBuilder ensambladoBld = dominioAplicacion.DefineDynamicAssembly(nombre_Del_Ensamblado, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduloBld = ensambladoBld.DefineDynamicModule("<MOD");
        TypeBuilder claseContenedoraBld = moduloBld.DefineType("claseContenedora");
        MethodBuilder mainBld = claseContenedoraBld.DefineMethod("main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
        ILGenerator il = mainBld.GetILGenerator();

        FieldBuilder campoBld = claseContenedoraBld.DefineField("x", typeof(int), FieldAttributes.Public | FieldAttributes.Static);
        il.Emit(OpCodes.Ldc_I4, 2);
        il.Emit(OpCodes.Stsfld, campoBld);

        FieldBuilder campoBld1 = claseContenedoraBld.DefineField("x1", typeof(int), FieldAttributes.Public | FieldAttributes.Static);

        il.Emit(OpCodes.Ldc_I4, 2);
        il.Emit(OpCodes.Stsfld, campoBld1);

        il.Emit(OpCodes.Ldftn, campoBld);
      //il.Emit(OpCodes.Unbox, typeof(int));
      //il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);


        il.Emit(OpCodes.Ldftn, campoBld1);
        //il.Emit(OpCodes.Unbox, typeof(int));
        il.Emit(OpCodes.Stloc_1);
        il.Emit(OpCodes.Ldloc_1);
        //il.Emit(OpCodes.Box, typeof(int));
        //il.Emit(OpCodes.Ldftn, campoBld1);
        //il.Emit(OpCodes.Unbox, typeof(int));

        il.Emit(OpCodes.Add);
        il.Emit(OpCodes.Pop);
        //il.Emit(OpCodes.Stsfld, campoBld1);




        il.Emit(OpCodes.Ret);


        Type t = claseContenedoraBld.CreateType();

        object ptInstance = Activator.CreateInstance(t, new Type[] { });

        t.InvokeMember("main", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
            null,
            ptInstance,
            new object[0]);

        var x = t.GetField("x");

    }

1 个答案:

答案 0 :(得分:3)

您的IL无效。例外并不是很好,但你正在修补JIT编译器的内容。 Opcodes.Ldsftn 做你认为它做的事情,你需要Ldsfld来加载一个字段。我无法弄清楚你要写的是什么代码,但这应该是接近的。它无论如何都不会崩溃:

        FieldBuilder campoBld = claseContenedoraBld.DefineField("x", typeof(int), FieldAttributes.Public | FieldAttributes.Static);
        il.Emit(OpCodes.Ldc_I4, 2);
        il.Emit(OpCodes.Stsfld, campoBld);
        FieldBuilder campoBld1 = claseContenedoraBld.DefineField("x1", typeof(int), FieldAttributes.Public | FieldAttributes.Static);
        il.Emit(OpCodes.Ldc_I4, 2);
        il.Emit(OpCodes.Stsfld, campoBld1);
        il.Emit(OpCodes.Ldsfld, campoBld);
        il.Emit(OpCodes.Ldsfld, campoBld1);
        il.Emit(OpCodes.Add);
        il.Emit(OpCodes.Pop);
        il.Emit(OpCodes.Ret);

找出IL的最佳方法是首先用C#编写代码,然后用Ildasm.exe反汇编它以查看IL的样子。