【问题标题】:System.Reflection.Emit - If Statement GenerationSystem.Reflection.Emit - If 语句生成
【发布时间】:2016-04-05 00:12:54
【问题描述】:

我正在尝试了解如何在 C# 中使用 ILGenerator 生成 If 语句。

这是我的代码:(ilg 是一个 ILGenerator)

ilg.Emit(OpCodes.Ldc_I4_1);
Label start = ilg.DefineLabel();
ilg.Emit(OpCodes.Brfalse, start);
ilg.Emit(OpCodes.Ldstr, "Hello");
ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilg.MarkLabel(start);

一些注意事项:

  • 单独调用 Console.WriteLine 效果很好。
  • 这是我运行生成的 exe 时遇到的错误:

未处理的异常:System.InvalidProgramException:公共语言运行时检测到无效程序。在Testing.Test.Main(String[])

【问题讨论】:

标签: c# reflection compiler-construction clr il


【解决方案1】:

您的代码几乎可以正常工作,只是忘记将OpCodes.Ret 放在末尾,请查看有效的代码:

public static void Main(string[] args)
{
    var dynamicMethod = new DynamicMethod("PrintHello", typeof(void), null);
    var ilGenerator = dynamicMethod.GetILGenerator();
    ilGenerator.Emit(OpCodes.Ldc_I4_1);
    var toEnd = ilGenerator.DefineLabel();
    ilGenerator.Emit(OpCodes.Brfalse, toEnd);
    ilGenerator.Emit(OpCodes.Ldstr, "Hello");
    ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
    ilGenerator.MarkLabel(toEnd);
    ilGenerator.Emit(OpCodes.Ret);

    var @delegate = (Action)dynamicMethod.CreateDelegate(typeof(Action));
    @delegate();
}

然后你会有这个输出

你好

如果你评论这行ilGenerator.Emit(OpCodes.Ret);你会得到这个异常

System.InvalidProgramException:公共语言运行时检测到无效程序。

记住,C# 中的每个方法都必须有 OpCode.Ret

如果你的 Main 方法是空的,像这样

public static void Main(string[] args)
{
}

生成的IL(在调试模式下,未经优化)将是这个

.method public hidebysig static void Main (string[] args) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 2 (0x2)
    .maxstack 8
    .entrypoint

    IL_0000: nop
    IL_0001: ret
} // end of method Program::Main

生成的IL(在发布模式下,带有优化)将是这个

.method public hidebysig static void Main (string[] args) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 1 (0x1)
    .maxstack 8
    .entrypoint

    IL_0000: ret
} // end of method Program::Main

【讨论】:

  • 谢谢! :) 完美运行。
  • 谢谢@DaniloLekovic 我很高兴这个答案对你有用。
猜你喜欢
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 2011-10-25
  • 1970-01-01
相关资源
最近更新 更多