Creating Dymamic Method throws en 异常

Creating Dymamic Method throws en exception

提问人:Tadeusz 提问时间:3/16/2022 更新时间:3/16/2022 访问量:44

问:

我想创建一些具有 2 个周期的动态方法:首先将一些 N 值推送到评估堆栈上,其次 - 这些 N 值从堆栈中弹出。但 CreateMethod 会引发 InvalidProgramException。我怎样才能实现我想要什么? 我的代码是:

public static Action MakeSimpleAction()
{
    var dm = new DynamicMethod("evil", typeof(void), new Type[] {  }, true);
    var il = dm.GetILGenerator(); Label startCycle;
    il.DeclareLocal(typeof(int));   //i = 0

    //Method 1: All is OK!
    //il.Emit(OpCodes.Ldc_I4_0);  //Push 0 onto evaluation stack
    //il.Emit(OpCodes.Pop);  //Pop value from evaluation stack
    //il.Emit(OpCodes.Ret);

    //Method 2: In cycles - throws an exception!

    //First cycle: for (int i = 0; i < 5; i ++) Push(0);
    il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc_0);    //i = 0
    il.MarkLabel(startCycle = il.DefineLabel());
    il.Emit(OpCodes.Ldc_I4_0);  //Push 0 onto evaluation stack
    
    il.Emit(OpCodes.Ldloc_0);   //i ++
    il.Emit(OpCodes.Ldc_I4_1);
    il.Emit(OpCodes.Add);
    il.Emit(OpCodes.Stloc_0);
    //if i < 5 goto startCycle
    il.Emit(OpCodes.Ldloc_0);
    il.Emit(OpCodes.Ldc_I4_5);
    il.Emit(OpCodes.Clt);   //if i < 5
    il.Emit(OpCodes.Brtrue_S, startCycle);

    //Second cycle: for (int i = 0; i < 5; i ++) Pop();
    il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc_0);    //i = 0
    il.MarkLabel(startCycle = il.DefineLabel());
    il.Emit(OpCodes.Pop);  //Pop value from evaluation stack

    il.Emit(OpCodes.Ldloc_0);   //i ++
    il.Emit(OpCodes.Ldc_I4_1);
    il.Emit(OpCodes.Add);
    il.Emit(OpCodes.Stloc_0);
    //if i < 5 goto startCycle
    il.Emit(OpCodes.Ldloc_0);
    il.Emit(OpCodes.Ldc_I4_5);
    il.Emit(OpCodes.Clt);   //if i < 5
    il.Emit(OpCodes.Brtrue_S, startCycle);

    il.Emit(OpCodes.Ret);

    //throw System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
    return (Action)dm.CreateDelegate(typeof(Action));
}
C# Reflection.Emit 中间语言 动态方法

评论

0赞 Jeroen van Langen 3/16/2022
如果您在 SharpLab 上编写 c# 代码并将生成的 IL 与您的源代码进行比较,该怎么办?
0赞 Kirk Woll 3/16/2022
如果要使用 Reflection.Emit,则需要知道如何使用 PEVerify.exe,它将扫描程序集并提供有关程序无效原因的诊断反馈。为了使用它,您必须(暂时)将生成的程序集保存到磁盘。
0赞 Tadeusz 3/16/2022
没有 C# 代码用于我想做的事情 :((
0赞 Jeroen van Langen 3/16/2022
@Tadeusz您也可以使用sharplab直接编写IL,因此开发周期更快。

答: 暂无答案