gpt4 book ai didi

c# - 像 C# 方法 IL 一样发出 IL 但获取 System.InvalidProgramException : Common Language Runtime detected an invalid program

转载 作者:太空宇宙 更新时间:2023-11-03 22:30:18 26 4
gpt4 key购买 nike

像 C# 方法 IL 一样发出 IL 但获取 System.InvalidProgramException:公共(public)语言运行时检测到无效程序。

示例:

    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>

我试着按照我的逻辑写一个新版本,它成功了。
但它是 IL 不等于演示方法的 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));

你的第二个版本没有使用本地化,所以它没有这个问题。

第一个版本是编译器在 Debug模式下发出的,但在 Release模式下它更像是你的第二个例子(除了 nop 是不必要的)。

关于c# - 像 C# 方法 IL 一样发出 IL 但获取 System.InvalidProgramException : Common Language Runtime detected an invalid program,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58129941/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com