【问题标题】:Why do I get System.InvalidProgramException: Common Language Runtime detected an invalid program为什么我得到 System.InvalidProgramException:公共语言运行时检测到无效程序
【发布时间】:2017-03-04 22:43:46
【问题描述】:

我只是想生成只生成一个 int 常量的代码。这是代码: 字符串名称 = Path.GetFileNameWithoutExtension(outputPath); 字符串文件名 = Path.GetFileName(outputPath);

AssemblyName assemblyName = new AssemblyName(name);

AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); //, Path.GetDirectoryName(outputPath));
ModuleBuilder moduleBuilder = assembly.DefineDynamicModule(name, filename);

TypeBuilder programType = moduleBuilder.DefineType(name + ".Program");
MethodBuilder mainMethod = programType.DefineMethod("Main", MethodAttributes.Static, typeof(void), System.Type.EmptyTypes);
assembly.SetEntryPoint(mainMethod);
ILGenerator generator = mainMethod.GetILGenerator();
generator.Emit(OpCodes.Ldc_I4, (int)Value);
generator.Emit(OpCodes.Ret);
programType.CreateType();
assembly.Save(filename);

当我执行 .exe 时,它​​给出了异常 为什么?

【问题讨论】:

  • 正如它所说,您的 MSIL 不正确。堆栈不平衡,请考虑删除 Ldc_I4 指令。
  • 你的意思是:堆栈不平衡?如果我删除 Ldc_I4 指令,那么它什么也不做,那不是我想要的。我想要的行为就像声明一个可以使用或不使用的值。我可以这样做吗?

标签: compiler-errors .net-assembly system.reflection reflection.emit ilgenerator


【解决方案1】:

正如 here 所指定的,您定义了一个返回类型为 void 的方法。

但是您生成的 IL 返回一个 int(在 ret 指令之前的堆栈内容)。

如果您将 defineMethod 行替换为

MethodBuilder mainMethod = programType.DefineMethod("Main", MethodAttributes.Static, typeof(int), System.Type.EmptyTypes);

你会做对的。

您通常可以使用ILspy 反汇编您的可执行文件(或库)来发现大部分 IL 错误。

在你的情况下,你会看到:

static void Main()
{
    12;
}

这显然是错误的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 2016-08-13
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2017-05-05
    • 2011-05-05
    相关资源
    最近更新 更多