我创建了一个动态方法,即:
class MyClass
{
private void object _o = <whatever>;
void CreateDynamicMethod()
{
DynamicMethod dm = new DynamicMethod("Test", ...);
// emit various IL
// need to push _o onto stack here
}
}
第二条评论,我想将_o 当前的值推入堆栈。我不想推送_o的引用,因为它会随着构建动态方法而改变。
所以说_o = 5,我想推5,如果_o包含List,我想推送它,如果它包含一个字符串,我想推送字符串。
动态方法(Test)是一个静态方法,它显然不会有MyClass的this指针来获取字段。我甚至无法将它放在静态变量中,因为在执行Test()期间会访问它,而不是在我构建方法时。
即使我有这个指针,_o也不会在Test()执行时具有正确的值。
有什么建议吗?
答案 0 :(得分:1)
您无法传递指针,因为它无效。但是,您可以传入句柄。我过去使用的一种技术是将整数值作为索引导入堆栈,作为某些静态可用资源的索引(如静态类中的字典,或网络资源,或其他),它将保存对象的值在将来这个方法将需要它。
这就是编译器按顺序执行虚方法调用的方式。它不知道它将在编译时调用哪个实例方法版本 - 它不知道。因此,表示方法的标记被压入堆栈而不是指向方法本身的指针。然后,该令牌将用于在运行时使用位于众所周知位置的资源执行vtable查找,并将令牌作为该资源的索引。
您需要完成任务的是您自己的vtable版本,并且您将使用整数作为令牌。 Ldc.i4.s是将所需的任何整数常量压入堆栈的IL指令。这是你的令牌:)在调用静态方法来检索你的对象之前将它推入堆栈。
确保在调用方法之前存储对象;)
有一些方法可以操纵堆栈来存储一个序列化的代理对象,然后该方法可以在调用它时进行反序列化。但如果我在这里解释一下,我会受到抨击。