【问题标题】:__methodptr in decompiled C# code反编译的 C# 代码中的 __methodptr
【发布时间】:2015-02-04 20:36:55
【问题描述】:

我正在使用 dotPeek 深入了解 C# 编译器的魔力,反编译代码中的某些内容引起了我的注意。我正在创建一个Action<int> 实例并将其传递给Start() 方法,编译器生成以下内容:

new Program().Start(new Action<int>((object) cDisplayClass1, __methodptr(<Main>b__0)));

我大致了解这里发生了什么,我唯一的问题是 __methodptr 是什么?确切地说,它来自哪里?是来自伊利诺伊吗? dotPeek 对它或包含它的程序集一无所知。谷歌也没有给出确切的答案,只给出相同的 sn-ps 代码,没有任何解释。

谢谢!

【问题讨论】:

  • 这是反编译器中的一个错误。程序集是由 Roslyn 编译的吗?
  • 任何认为他们需要混淆器的人没有编写足够的匿名委托、迭代器、lambda 表达式、Linq 和异步方法。那种不受反编译影响的代码。 Afaik,dotPeek 通常还会发出 // ISSUE: method pointer 评论以警告您它放弃了。

标签: c# delegates decompiling


【解决方案1】:

__methodptr对应IL指令ldftn,粗略地说ldftn将“函数指针”加载到评估堆栈上。这是一个示例:

反编译的源码:

   private static void Main(string[] args)
    {
      Program.\u003C\u003Ec__DisplayClass0_0 cDisplayClass00 = new Program.\u003C\u003Ec__DisplayClass0_0();
      cDisplayClass00.xx = 100;
      // ISSUE: method pointer
      new Action((object) cDisplayClass00, __methodptr(\u003CMain\u003Eb__0))();
      Console.WriteLine(cDisplayClass00.xx);
    }

IL:

1 加载函数指针类::方法

IL_000f: ldloc.0      // cDisplayClass00
IL_0010: ldftn        instance void TestIL.Program/'<>c__DisplayClass0_0'::'<Main>b__0'()

2 new 一个传递对象和函数指针的委托

IL_0016: newobj       instance void [mscorlib]System.Action::.ctor(object, native int)
IL_001b: stloc.1      // V_1

3 调用委托

IL_001c: ldloc.1      // V_1
IL_001d: callvirt     instance void [mscorlib]System.Action::Invoke()
IL_0022: nop 

【讨论】:

    【解决方案2】:

    你应该如下替换代码:

    新动作(cDisplayClass00.Mainb__0))();

    可以这么说,指向自动生成类的自动生成方法的函数指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      • 2017-08-18
      • 2019-09-09
      • 1970-01-01
      相关资源
      最近更新 更多