繁体   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