【问题标题】:Why i'm getting the exception: Common Language Runtime detected an invalid program为什么我收到异常:公共语言运行时检测到无效程序
【发布时间】:2014-07-14 15:39:54
【问题描述】:

我正在使用 Mono cecil 来自动实现 propertychanged 接口。一切正常,直到今天我收到异常 Common Language Runtime 检测到无效程序。我的 mono cecil c# 代码是:

ILProcessor MSILWorker = prop.SetMethod.Body.GetILProcessor();
MSILWorker.Body.InitLocals = true;
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[0], MSILWorker.Create(OpCodes.Nop));
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[1], MSILWorker.Create(OpCodes.Ldarg_0));
Instruction propertyName = MSILWorker.Create(OpCodes.Ldflda, field);
MSILWorker.InsertBefore(MSILWorker.Body.Instructions[3], propertyName);
MSILWorker.InsertAfter(MSILWorker.Body.Instructions[4], MSILWorker.Create(OpCodes.Ldstr, prop.Name));
Instruction callRaisePropertyChanged = MSILWorker.Create(OpCodes.Call, method_reference);
MSILWorker.Replace(MSILWorker.Body.Instructions[6], callRaisePropertyChanged);
MSILWorker.InsertBefore(MSILWorker.Body.Instructions.Last(), MSILWorker.Create(OpCodes.Pop));

生成的 il 代码为:

.method public hidebysig newslot specialname virtual final 
        instance void  set_CreateDate(valuetype [mscorlib]System.DateTime 'value') cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       21 (0x15)
  .maxstack  4
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldflda     valuetype [mscorlib]System.DateTime Framework.Data.Base.BaseEntity::'<CreateDate>k__BackingField'
  IL_0008:  ldarg.1
  IL_0009:  ldstr      "CreateDate"
  IL_000e:  call       instance void Framework.Data.Base.BaseEntity::SetField<valuetype [mscorlib]System.DateTime>(!!0&,
                                                                                                                   !!0,
                                                                                                                   string)
  IL_0013:  pop
  IL_0014:  ret
} // end of method BaseEntity::set_CreateDate

我尝试与用 C# 编写的另一个字段的属性进行比较,逻辑完全相同,生成的 IL 代码为:

.method public hidebysig newslot specialname virtual final 
        instance void  set_LastModifiedDate(valuetype [mscorlib]System.DateTime 'value') cil managed
{
  // Code size       21 (0x15)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldflda     valuetype [mscorlib]System.DateTime Framework.Data.Base.BaseEntity::_LastModifiedDate
  IL_0008:  ldarg.1
  IL_0009:  ldstr      "LastModifiedDate"
  IL_000e:  call       instance void Framework.Data.Base.BaseEntity::SetField<valuetype [mscorlib]System.DateTime>(!!0&,
                                                                                                                   !!0,
                                                                                                                   string)
  IL_0013:  nop
  IL_0014:  ret
} // end of method BaseEntity::set_LastModifiedDate

有人可以帮助我吗?我做错了什么?

谢谢

【问题讨论】:

  • Protip:在生成的 IL 上运行 PEVerify,会告诉你到底哪里出了问题
  • 嗨 Leppie,我尝试使用 PEVerify,但它没有显示任何重要信息。您会使用哪些参数调用 PEVerify?

标签: c# mono inotifypropertychanged il


【解决方案1】:

你的筹码不平衡。 C# 生成的示例在 IL_0013 处有一个 nop,您在其中有一个 pop

我的猜测是您正在调用void 方法,因此不需要丢弃结果。

删除MSILWorker.InsertBefore(MSILWorker.Body.Instructions.Last(), MSILWorker.Create(OpCodes.Pop));

【讨论】:

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