[英]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
实例。 例如,您可以改为传递托管函数指针。 这些就是ldftn
和ldvirtftn
指令返回的内容。 然后,您可以使用calli
指令来调用其中之一。 您将需要使用SignatureHelper
类构造“ call-site description”( calli
期望作为操作数)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.