0

我正在尝试将两种方法合并在一起(一种来自我的项目,一种来自 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 有什么问题。

我使用dnlibC# 来获取方法的 IL 代码,然后将两个代码块连接在一起(我剥离了nopandret语句(最后一个除外))。为了重新编译我使用该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
4

1 回答 1

1

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

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

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

于 2017-12-29T18:49:45.033 回答