生成的IL代码无效

问题描述 投票:-1回答:1

我正在尝试将两个方法合并在一起(我的项目中的一个方法,一个来自dll的方法)并将它们写入dll。原始代码如下所示:

 .method public hidebysig static class Storage.DataMap 
    Create() cil managed 
  {
    .maxstack 8

    // [22 7 - 22 70]
    IL_0000: call         unmanaged stdcall native int Storage.DataMapPlugin::DataMap_CreateEmptyDataMap()
    IL_0005: newobj       instance void Storage.DataMap::.ctor(native int)
    IL_000a: ret          

  } // end of method DataMap::Create

我想在这段代码中添加一个简单的Console.WriteLine,我最终得到以下内容:(来自反编译器)

  .method public hidebysig static class Storage.DataMap 
    Create() cil managed 
  {
    .maxstack 8

    // [22 7 - 22 44]
    IL_0000: ldstr        "Hello World"
    IL_0005: call         void [mscorlib]System.Console::WriteLine(string)

    // [23 7 - 23 70]
    IL_000a: call         unmanaged stdcall native int Storage.DataMapPlugin::DataMap_CreateEmptyDataMap()
    IL_000f: newobj       instance void Storage.DataMap::.ctor(native int)
    IL_0014: ret          

  } // end of method DataMap::Create

我的反编译器无法对此进行反编译(dotPeek),因此我假设我生成的IL无效。但是,我不确定我生成的IL有什么问题。

我正在使用带有C#的dnlib来获取方法的IL代码,然后将Concat的两个代码块一起使用(我删除了nopret语句(除了最后一个))。要重新编译代码我使用ModuleDef#Write(String)函数,我在编写自己的IL语句时已经成功,但在合并已有的语句时却没有。

(以下IL全部从控制台打印,而不是从反编译器打印) 原文第1部分IL:

IL_0000: nop
IL_0001: ldstr "Hello World"
IL_0006: call System.Void System.Console::WriteLine(System.String)
IL_000B: nop
IL_000C: ret

原文第2部分IL:

IL_0000: call System.IntPtr Storage.DataMapPlugin::DataMap_CreateEmptyDataMap()
IL_0005: newobj System.Void Storage.DataMap::.ctor(System.IntPtr)
IL_000A: ret

合并IL:

IL_0001: ldstr "Hello World"
IL_0006: call System.Void System.Console::WriteLine(System.String)
IL_0000: call System.IntPtr Storage.DataMapPlugin::DataMap_CreateEmptyDataMap()
IL_0005: newobj System.Void Storage.DataMap::.ctor(System.IntPtr)
IL_000A: ret
c# cil dnlib
1个回答
0
投票

我解决了自己的问题。正如多个人在评论中正确指出的那样,IL是正确的。问题与我的代码或生成的IL无关,而与反编译器dotPeek无关。

发生的事情如下:我第一次生成了DLL,但IL错了(它有2个返回语句),用dotPeek反编译它,看到IL格式错误。我再次这样做,但使用正确的IL(只有1个返回语句)并删除旧的DLL,将新的DLL重命名为旧的,已删除的,一个。然而,DotPeek并不喜欢这样,它会显示更新的IL,但不会显示更新的代码。

经过多次重新启动并删除/重新添加程序集后,我发现情况就是如此。 dnSpy似乎比dotPeek工作得更好,所以我将来会使用它。

© www.soinside.com 2019 - 2024. All rights reserved.