尝试调试发出错误,是否有一种简单的方法可以找到有关由发出的代码引起的异常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
Run Code Online (Sandbox Code Playgroud)
我得到了"调用目标引发了异常.当我尝试调用Invoke倒数第二行时.发送代码一直存在问题,但如果我能弄清楚如何获得有意义的异常,那可能不那么痛苦想法?
获得无用的异常是生成IL代码的乐趣的一部分.当你得到"调用目标抛出异常"时,你可以查看InnerException属性,看看你是否可以在那里获得更多有用的东西:
try
myObj.GetType().GetMethod("MyMethod").Invoke(myObj, [|2; 3|]) |> printfn "%A"
with
e -> printfn "%A" e.InnerException
Run Code Online (Sandbox Code Playgroud)
在这种情况下,内部异常说:
System.InvalidProgramException:公共语言运行时检测到无效程序.
这只是意味着您生成的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)
Run Code Online (Sandbox Code Playgroud)