簡體   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