Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发出类似IL的C方法IL,但获取System.InvalidProgrameException:公共语言运行库检测到无效程序_C#_Clr_Emit - Fatal编程技术网

C# 发出类似IL的C方法IL,但获取System.InvalidProgrameException:公共语言运行库检测到无效程序

C# 发出类似IL的C方法IL,但获取System.InvalidProgrameException:公共语言运行库检测到无效程序,c#,clr,emit,C#,Clr,Emit,发出类似IL的C方法IL,但获取System.InvalidProgrameException:公共语言运行库检测到无效程序 例如: public static int BoolToInt(this bool input) { return input ? 1 : 0; } IL代码为: ExtensionDataGetter.BoolToInt: IL_0000: nop IL_0001: ldarg.0 IL_0002

发出类似IL的C方法IL,但获取System.InvalidProgrameException:公共语言运行库检测到无效程序

例如:

    public static int BoolToInt(this bool input)
    {
        return input ? 1 : 0;
    }
IL代码为:

ExtensionDataGetter.BoolToInt:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  brtrue.s    IL_0007
IL_0004:  ldc.i4.0    
IL_0005:  br.s        IL_0008
IL_0007:  ldc.i4.1    
IL_0008:  stloc.0     
IL_0009:  br.s        IL_000B
IL_000B:  ldloc.0     
IL_000C:  ret         
我尝试使用Emit IL创建此方法:

class Program
{
    static void Main(string[] args)
    {
        var result = CreateFunc()(true);
        Console.WriteLine(result);
    }

    static Func<bool, int> CreateFunc()
    {
        var dm = new DynamicMethod("Test" + Guid.NewGuid().ToString(), typeof(int), new[] { typeof(bool) });
        var il = dm.GetILGenerator();

        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldarg_0);

        var labelTrue = il.DefineLabel();
        var labelStloc = il.DefineLabel();
        var labelReturn = il.DefineLabel();

        il.Emit(OpCodes.Brtrue_S, labelTrue); 
        il.Emit(OpCodes.Ldc_I4_0);
        il.Emit(OpCodes.Br_S, labelStloc);
        il.MarkLabel(labelTrue);
        il.Emit(OpCodes.Ldc_I4_1);
        il.MarkLabel(labelStloc);
        il.Emit(OpCodes.Stloc_0);

        il.Emit(OpCodes.Br_S, labelReturn); 
        il.MarkLabel(labelReturn);
        il.Emit(OpCodes.Ldloc_0); 
        il.Emit(OpCodes.Ret);

        var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(bool), typeof(int));
        return (Func<bool, int>)dm.CreateDelegate(funcType);
    }
}
但要避免错误

System.InvalidProgramException
  HResult=0x8013153A
  Message=Common Language Runtime detected an invalid program.
  Source=<Cannot evaluate the exception source>
  StackTrace:
<Cannot evaluate the exception stack trace>
我试着根据我的逻辑写一个新版本,这是成功的。 但这不是eqauls演示方法的IL

using System;
using System.Reflection;
using System.Reflection.Emit;


class Program
{
    static void Main(string[] args)
    {
        var func = CreateFunc();
        Console.WriteLine(func(true));
        Console.WriteLine(func(false));
    }

    static Func<bool, int> CreateFunc()
    {
        var dm = new DynamicMethod("Test" + Guid.NewGuid().ToString(), typeof(int), new[] { typeof(bool) });

        var il = dm.GetILGenerator();
        var labelTrue = il.DefineLabel();

        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Brtrue_S, labelTrue); 
        il.Emit(OpCodes.Ldc_I4_0);
        il.Emit(OpCodes.Ret);
        il.MarkLabel(labelTrue);
        il.Emit(OpCodes.Ldc_I4_1);
        il.Emit(OpCodes.Ret);

        var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(bool), typeof(int));
        return (Func<bool, int>)dm.CreateDelegate(funcType);
    }
}



由于使用stloc.0将值存储在局部变量中,因此需要声明它:

var il = dm.GetILGenerator();
il.DeclareLocal(typeof(int));
您的第二个版本没有使用局部变量,因此没有此问题


第一个版本是编译器在调试模式下发出的,但在发布模式下,它更像您的第二个示例,除了不需要的nop之外。

因为您使用stloc.0将值存储在局部变量中,所以需要声明它:

var il = dm.GetILGenerator();
il.DeclareLocal(typeof(int));
您的第二个版本没有使用局部变量,因此没有此问题


第一个版本是编译器在调试模式下发出的,但在发布模式下,它更像您的第二个示例,只是nop是不必要的。

查看C编译器生成的IL是一个避免麻烦的好主意。但请务必查看发布版本,它会将您从这个bug中解救出来。@HansPassant谢谢!这对我来说是一个很重要的概念。看看C编译器生成的IL是一个避免麻烦的好主意。但请务必查看发布版本,它会将您从这个bug中解救出来。@HansPassant谢谢!这对我来说是个重要的概念。