语言运行时检测到无效程序

语言运行时检测到无效程序

以下是我的 C# 代码:

List<int> list = new List<int>();
for(int Count = 0; Count < 5; Count++)
    list.Add(Count);
return list;

我对应的发出代码如下:
LocalBuilder list = ILout.DeclareLocal(typeof(List<int>));
LocalBuilder Count = ILout.DeclareLocal(typeof(int));
LocalBuilder CmpRes = ILout.DeclareLocal(typeof(bool));
ConstructorInfo DictConstrctor = typeof(List<int>).GetConstructor(new Type[] { });
MethodInfo methodinfo_add = typeof(List<int>).GetMethod("Add", new[] { typeof(int) });
Label IL_001C = ILout.DefineLabel();
Label IL_000B = ILout.DefineLabel();

ILout.Emit(OpCodes.Newobj, DictConstrctor);
ILout.Emit(OpCodes.Stloc_0, list);
ILout.Emit(OpCodes.Ldc_I4_0);
ILout.Emit(OpCodes.Stloc_1, Count);

ILout.Emit(OpCodes.Br_S, IL_001C);
ILout.MarkLabel(IL_000B);
ILout.Emit(OpCodes.Ldloc_0, list);
ILout.Emit(OpCodes.Ldloc_1, Count);
ILout.Emit(OpCodes.Call, methodinfo_add);

ILout.Emit(OpCodes.Ldloc_1, Count);
ILout.Emit(OpCodes.Ldc_I4_1);
ILout.Emit(OpCodes.Add);

ILout.Emit(OpCodes.Stloc_1, Count);
ILout.MarkLabel(IL_001C);
ILout.Emit(OpCodes.Ldloc_1, Count);
ILout.Emit(OpCodes.Ldc_I4_2);
ILout.Emit(OpCodes.Clt);
ILout.Emit(OpCodes.Stloc_3, CmpRes);
ILout.Emit(OpCodes.Ldloc_3, CmpRes);
ILout.Emit(OpCodes.Brtrue_S, IL_000B);

ILout.Emit(OpCodes.Ldloc_0, list);
ILout.Emit(OpCodes.Ret);

它抛出异常 - “公共(public)语言运行时检测到无效程序。”。

我在这里做错了什么?
任何帮助表示赞赏。

最佳答案

ILout.Emit(OpCodes.Stloc_1, Count);


ILout.Emit(OpCodes.Ldloc_1, Count);

没有意义。如果您明确说“使用本地 1”,则不需要其他参数

同样地:
ILout.Emit(OpCodes.Stloc_3, CmpRes);
ILout.Emit(OpCodes.Ldloc_3, CmpRes);

虽然坦率地说,我不确定 CmpRes 是否有任何有用的用途;没有意义存储和加载 - 只需将其留在堆栈中

注意:如果Count是“local 1”,那么CmpRes就是“local 2”;没有“本地 3”,因此 Stloc_3Ldloc_3 格式错误。

再次在这里:
ILout.Emit(OpCodes.Ldloc_0, list);
ILout.Emit(OpCodes.Ldloc_1, Count);

——

接下来我们开始通话;你在做一个静态调用:
ILout.Emit(OpCodes.Call, methodinfo_add);

但这是一个对象的实例方法,所以应该是一个虚拟调用。

在这里又一次本地摸索:
ILout.Emit(OpCodes.Ldloc_1, Count);

和这里:
ILout.Emit(OpCodes.Stloc_1, Count);

和这里:
ILout.Emit(OpCodes.Ldloc_0, list);

但是,我也严重怀疑此循环(即使已修复)是​​否会执行您期望的操作 - 如果我没看错,它实际上是:
var list = new List<int>();
for(int i [= 0] ; i < 2 ; i++) // note the 0 here implicit not explicit
{
    list.Add(i);
}
return list;

关于c# - 将对象添加到 IL Emit 中的循环列表 - 公共(public)语言运行时检测到无效程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38095469/

10-10 21:34