有人可以向我解释在通过reflection.emit进行函数调用之前需要加载到堆栈中的内容吗?
我有一个非常简单的方法
public static void Execute(string 1, string 2)
我想动态地在下面的类中生成该方法(忘记其余的,我把它们整理出来)
public class Test{
public string s1;
public void Run(string s2)
{
MyOtherClass.Execute(s2,s1)
}
}
我有上述测试的副本供参考,我注意到在“通话”之前发出了以下操作码。
问题是ldarg_0在那里做什么?我只需要2个参数来调用,为什么CLR需要将ldarg_0推送到堆栈?
答案 0 :(得分:9)
arg.0
包含this
,ldfld string Test:s1
需要将this.s1
推送到堆栈。
.method public hidebysig instance void Run(string s2) cil managed
{
.maxstack 8 // maximum stack size 8
ldarg.1 // push argument s2
ldarg.0 // push this
ldfld string Test::s1 // pop this, push this.s1
call void MyOtherClass::Execute(string, string) // call
ret // return
}
答案 1 :(得分:2)
如果方法不是静态的,您需要按声明的顺序推送方法的参数和对象引用。在您的测试用例中,您正在访问成员字段(s1
),因此您需要this
参考。这就是ldarg_0
提供的内容。随后的ldfld
会弹出this
引用,并将字段的值推送到评估堆栈。