繁体   English   中英

使用Reflection.Emit在堆栈上使用MethodInfo实例调用方法

[英]Call a method using a MethodInfo instance on the stack using Reflection.Emit

我正在使用Reflection.Emit构建数学表达式解析器(例如2+2 )。 一个类接受一个后缀表达式(例如2+2 ),将其转换为后缀表达式(例如2 2 + ),然后另一个类将该后缀表达式编译为IL并创建DynamicMethod 从那里,可以像在编译时创建表达式一样以类似的速度对其进行求值。

该编译器还支持隐式乘法,因此类似x(2 + 2)x * (2 + 2)

现在,我正在尝试实现用户定义的函数(例如f(x) )。 当我尝试区分如上所示的隐式乘法和用户定义的函数时,会出现问题。 例如,如果用户输入x(5) ,我如何知道他们是要将x乘以5还是使用参数5调用x函数?

为了解决这个问题,在前一种情况下,编译器在IL流中插入一个if语句。 它调用一个函数来确定该函数是否用x的标识符定义。 如果存在,那么它将通过out变量和局部变量将MethodInfo实例插入堆栈。

我的实际问题是,是否有可能在堆栈上使用MethodInfo实例执行与在编译过程中调用IlGenerator.Emit(OpCodes.Call, MethodInfo)速度等效的方法?

谢谢。

我知道的唯一允许您在堆栈上调用MethodInfo实例的方法是在其上调用Invoke方法。 我确定您已经意识到这种可能性,但是您担心它可能太慢。 我建议您尝试一下,并在压力下调整性能。 您可能会发现它足够快达到您的目的。

如果不是,那么您将不得不考虑如何重组设计,以免传递MethodInfo实例。 例如,您可以改为传递托管函数指针。 这些就是ldftnldvirtftn指令返回的内容。 然后,您可以使用calli指令来调用其中之一。 您将需要使用SignatureHelper构造“ call-site description”( calli期望作为操作数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM