gpt4 book ai didi

reflection - 如何从动态发出的程序集中获得有意义的异常?

转载 作者:行者123 更新时间:2023-12-03 09:54:00 27 4
gpt4 key购买 nike

尝试调试发出错误,是否有一种简单的方法可以找到有关异常 c 的更多信息由发出的代码引起?

例如,使用此代码:

let dynamicAssembly =
let asmName = new AssemblyName("MyAsm")
let asmBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run)
let moduleBuilder = asmBuilder.DefineDynamicModule("MyModule")
let typeBuilder = moduleBuilder.DefineType("MyDynamicType")
let methodBuilder =
let build = typeBuilder.DefineMethod("MyMethod", MethodAttributes.Public,
CallingConventions.Standard,
typeof<Int32>,
[|typeof<Int32>; typeof<Int32>|])
let ilGen = build.GetILGenerator()
ilGen.Emit(OpCodes.Ldarg_0)
ilGen.Emit(OpCodes.Ldarg_1)
ilGen.Emit(OpCodes.Add)
ilGen.Emit(OpCodes.Ret)

typeBuilder.CreateType() |> ignore
asmBuilder

let myType = dynamicAssembly.GetType("MyDynamicType")
let myObj = Activator.CreateInstance(myType)
myObj.GetType().GetMethod("MyMethod").Invoke(myObj, [|2; 3|]) |> ignore

当我尝试在倒数第二行调用 Invoke 时,我得到“调用的目标抛出了异常。发出代码一直是有问题的,但它可能会更少如果我能弄清楚如何获得有意义的异常,那会很痛苦。想法?

最佳答案

获取无用的异常是生成 IL 代码的乐趣之一。当你得到“Exception has been thrown by the target of an invocation”时,你可以查看 InnerException 属性,看看你是否能在那里得到更有用的东西:

try
myObj.GetType().GetMethod("MyMethod").Invoke(myObj, [|2; 3|]) |> printfn "%A"
with
e -> printfn "%A" e.InnerException

在这种情况下,内部异常表示:

System.InvalidProgramException: Common Language Runtime detected an invalid program.

这只是意味着您生成的 IL 是错误的 - 恐怕您不会得到更好的错误消息,但您可以将生成的程序集保存到磁盘并运行 peverify 或 Reflector/ILSpy 以查看他们将如何解释生成的代码。这意味着您需要添加另一个代码路径来生成正确的(非动态)程序集,但我认为这是值得的 - 您需要经常调试生成的 IL...

在这种情况下,问题是 Ldarg_0 引用 this(而不是第一个参数),因此您需要生成:

ilGen.Emit(OpCodes.Ldarg_1)
ilGen.Emit(OpCodes.Ldarg_2)
ilGen.Emit(OpCodes.Add)
ilGen.Emit(OpCodes.Ret)

关于reflection - 如何从动态发出的程序集中获得有意义的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15489745/

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