【问题标题】:How to inject IL with constant in run-time?如何在运行时以常量注入 IL?
【发布时间】:2012-06-16 21:55:53
【问题描述】:

我知道如何通过注入 IL 来创建动态方法,比如 a * 2;

但是我希望它像 a * b 一样,其中 b 是常数。

考虑一下。

int b = SomeClassInstance.Multiplier;

Func<int,int> MultA = CreateDynMethod(b);

for(int i = 0; i < 1000; i++)
{
    int a = GetValueSomewhere();
    int result = MultA(a);
    Console.WriteLine(result);
}

见.. b 对于所有 1000 次迭代都是相同的。但是我不知道它会是什么。 0 1 2 或其他。

我的问题是如何将 b 值作为常量嵌入到 IL 中。

这是非常重要的区别——我不想计算 var a * var b。 我想(例如,如果 b == 2 在运行时)创建执行 * 2 的 IL。

我有理由这样做。如果您按照所写的方式回答问题。谢谢。

编辑。这是我在你的帮助下可以写的。请说出你的想法

    static Func<int, int> IL_EmbedConst(int b)
    {
        var method = new DynamicMethod("EmbedConst", typeof(int), new[] { typeof(int) } );

        var il = method.GetILGenerator();

        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldc_I4, b);
        il.Emit(OpCodes.Mul);
        il.Emit(OpCodes.Ret);

        return (Func<int, int>)method.CreateDelegate(typeof(Func<int, int>));
    }

【问题讨论】:

    标签: c# dynamic .net-4.0


    【解决方案1】:

    你想要ldc.i4 操作码。

    这会将一个 int 加载到堆栈上,然后可以跟一个 mul

    你可以这样使用它:

    ilGen.Emit(OpCodes.Ldc_I4, b);
    

    顺便说一句,您实际上并不需要在这里从 IL 构建方法。这种方法也可以:

    Func<int, int> CreateDynMethod(int b)
    {
        return a => a * b;
    }
    

    【讨论】:

    • 从内存(今天还没有检查),我认为它优化到 ldc.i4.[b] 操作码,但 JIT 可能确实 快速检查一下,所以可能不重要
    • @MarcGravell:我刚刚做了一个(不是那么)快速测试,你是对的。现在我需要弄清楚我为什么会这样想。
    • 是的,它有效。多谢!让我将其与 func 进行基准测试
    • @Bobb:不要指望它会快得多。 C# 编译器 + JIT 编译器非常非常智能。
    • 再次感谢 Kendall,显然您的 CreateDynMethod 比 IL 注入的动态方法快 2 倍……但为什么呢?
    【解决方案2】:

    你可能想发出类似的东西

     ldarg.1
     ldc.i4 2
     mul
     ret
    

    您可以使用

    发出第二行
     il.Emit(OpCodes.Ldc_I4, 2);
    

    或者,为了清楚起见:

     int b = 2;
     il.Emit(OpCodes.Ldc_I4, b);
    

    http://msdn.microsoft.com/en-us/library/h3c68sh6http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      相关资源
      最近更新 更多