簡體   English   中英

如何將CIL代碼插入C#

[英]How to insert CIL code to C#

是否可以將IL代碼插入C#方法?

我剛發布了一個實用程序 ,它允許整個C#函數體使用自定義屬性自動替換為內聯IL。 與類似的實用程序一樣,這可以通過ILDASM / ILASM往返進行,可以將其設置為構建后步驟。 該工具還調整PDB,以便在調試器中的單個IL指令上保留單步執行和設置斷點。 它與其他一些往返IL內聯器的不同之處在於它(僅)替代整個函數體,如下所示:

    class MyClass
    {
        [ILFunc(@"
    .locals init ([0] int32 i_arg)
        ldc.i4.3
        ret
    ")]
        int MyFunc(int i_arg)
        {
            return 3;
        }
    };

對於高度性能關鍵的方法,我嘗試使用DynamicMethod來改進編譯器生成的IL,但發現由於委托調用開銷而導致的好處丟失了。 假設沒有您真正需要DynamicMethod運行時自定義,內聯IL給出了手動調整IL的優勢而沒有命中。

完整的源代碼位於http://www.glennslayden.com/code/c-sharp/inline-il

如果您正在尋找內聯IL(與C和C ++編譯器支持的內聯匯編的精神相同),則可以使用后編譯往返編譯來實現。

Mike Stall曾經為此編寫過一個工具 ,據我所知它已經相當成熟了:

除此之外,您可以使用支持Inline IL的F#。

DynamicMethod是在運行時完成此任務的輕量級方法。

Microsoft C#編譯器不支持在編譯時注入IL,但代碼編織工具可以作為后編譯步驟。

您需要的工具稱為Cecil ,是Mono項目的一部分。

您可以在此處獲得有關它的更多信息: http//www.mono-project.com/Cecil

引自上面的網站:

Cecil是由Jb Evain( http://evain.net/blog/ )編寫的庫,用於生成和檢查ECMA CIL格式的程序和庫。 它完全支持泛型,並支持一些調試符號格式。

用簡單的英語,使用Cecil,您可以加載現有的托管程序集,瀏覽所有包含的類型,動態修改它們並將修改后的程序集保存回磁盤。

我將自己的工具添加到此處已提供的解決方案列表中: InlineIL.Fody

這使用Fody組裝編織工具在構建時修改組件。 這意味着你要做的就是安裝一個NuGet包,在你的項目中添加一個配置文件,你就完成了。

然后,您將獲得一個簡單且類型安全的API來發出IL指令,您可以將其與C#代碼混合使用。 我認為用這種方式編寫IL比寫文本更容易,而且它比ILGenerator更方便,因為每個操作碼只有相關的重載才能獲得自己的方法。

這是一個例子, using static InlineIL.IL.Emit;

public static void ZeroInit<T>(ref T value)
    where T : struct
{
    Ldarg(nameof(value));
    Ldc_I4_0();
    Sizeof(typeof(T));
    Unaligned(1);
    Initblk();
}

這顯示了如何訪問C#當前未公開的initblk指令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM