【问题标题】:Simple generated MSIL throws "Operation could destabilize the runtime"简单生成的 MSIL 抛出“操作可能会破坏运行时”
【发布时间】:2013-02-23 14:52:39
【问题描述】:

我创建了一个非常简单的函数,它执行以下操作:

    public static object[] ToArray(int ID) {
        return new object[4];
    }

这是生成 MSIL 的代码。为什么这会引发“操作可能会破坏运行时”异常?我看不出有什么问题;它与 Reflector/Reflexil 中看到的组件完美匹配。

    // create method
    Type arrayType = typeof(object[]);
    Type intType = typeof(int);
    DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
    ILGenerator il = dm.GetILGenerator();

    // create the array -- object[]
    il.Emit(OpCodes.Ldc_I4, 4);
    il.Emit(OpCodes.Newarr, typeof(object));
    il.Emit(OpCodes.Stloc_0);

    // return the array
    il.Emit(OpCodes.Ldloc_0); 
    il.Emit(OpCodes.Ret);

    return dm;
    object result = dm.Invoke(null, new object[] { 1 });

【问题讨论】:

    标签: c# .net cil dynamicmethod


    【解决方案1】:

    我发现新变量没有正确声明。

    您需要使用DeclareLocal(typeof(T)) 语法来声明一个新的本地变量。

    更新后的代码sn-p如下:

        // create method
        Type arrayType = typeof(object[]);
        Type intType = typeof(int);
        DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
        ILGenerator il = dm.GetILGenerator();
    
        // create the array -- object[]
        LocalBuilder arr = il.DeclareLocal(arrayType);
        il.Emit(OpCodes.Ldc_I4, 4);
        il.Emit(OpCodes.Newarr, typeof(object));
        il.Emit(OpCodes.Stloc, arr);  // <-- don't use direct addresses, use refs to LocalBuilder instead
    
        // return the array
        il.Emit(OpCodes.Ldloc, arr); // <-- don't use direct addresses, use refs to LocalBuilder instead
        il.Emit(OpCodes.Ret);
    
        return dm;
        object result = dm.Invoke(null, new object[] { 1 });
    

    编辑:感谢Jon Skeet,最终优化后的代码sn-p如下:

        // create method
        Type arrayType = typeof(object[]);
        Type intType = typeof(int);
        DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
        ILGenerator il = dm.GetILGenerator();
    
        // create the array -- object[]
        LocalBuilder arr = il.DeclareLocal(arrayType);
        il.Emit(OpCodes.Ldc_I4, 4);
        il.Emit(OpCodes.Newarr, typeof(object));
    
        // return the array
        il.Emit(OpCodes.Ret);
    
        return dm;
        object result = dm.Invoke(null, new object[] { 1 });
    

    【讨论】:

    • 或者,完全摆脱 stloc/ldloc - 你不需要它。
    • 你甚至不需要DeclareLocal,因为你不再使用它了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    相关资源
    最近更新 更多