Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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
Reflection 如何从动态发出的程序集获取有意义的异常?_Reflection_F# - Fatal编程技术网

Reflection 如何从动态发出的程序集获取有意义的异常?

Reflection 如何从动态发出的程序集获取有意义的异常?,reflection,f#,Reflection,F#,尝试调试emit errors时,是否有一种简单的方法来查找有关异常c的更多信息 由发出的代码引起的 例如,使用此代码: let dynamicAssembly = let asmName = new AssemblyName("MyAsm") let asmBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run) let moduleBuilder = asmB

尝试调试emit errors时,是否有一种简单的方法来查找有关异常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
=
让asmName=newassemblyName(“MyAsm”)
让asmBuilder=AssemblyBuilder.DefinedDynamicAssembly(asmName,AssemblyBuilderAccess.Run)
让moduleBuilder=asmBuilder.DefinedDynamicModule(“MyModule”)
让typeBuilder=moduleBuilder.DefineType(“MyDynamicType”)
让methodBuilder=
让build=typeBuilder.DefineMethod(“MyMethod”,MethodAttributes.Public,
呼叫约定。标准,
类型,
[| typeof;typeof |])
让ilGen=build.GetILGenerator()
ilGen.Emit(操作码.Ldarg_0)
ilGen.Emit(操作码.Ldarg_1)
ilGen.Emit(操作码.添加)
ilGen.Emit(操作码Ret)
typeBuilder.CreateType()|>忽略
asmBuilder
让myType=dynamicAssembly.GetType(“MyDynamicType”)
让myObj=Activator.CreateInstance(myType)
myObj.GetType().GetMethod(“MyMethod”).Invoke(myObj,[| 2;3 |])|>忽略

我明白了“当我试图在倒数第二行调用
Invoke
时,调用的目标抛出了异常。发出代码总是有问题的,但如果我能找出如何获得有意义的异常,可能就不会那么痛苦了。想法?

获取无用的异常是生成IL代码的乐趣的一部分。当您获得“异常已被调用的目标抛出”时,您可以查看
InnerException
属性,看看是否可以从中获得更有用的内容:

try
  myObj.GetType().GetMethod("MyMethod").Invoke(myObj, [|2; 3|])  |> printfn "%A"
with 
  e -> printfn "%A" e.InnerException
在这种情况下,内部异常表示:

System.InvalidProgrameException:公共语言运行库检测到无效程序

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

在这种情况下,问题在于
Ldarg\u 0
引用了
(而不是第一个参数),因此您需要生成:

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

你捕获的异常的内部异常是什么?那很酷,除非没有。哦,我被证明是错的。谢谢你的建议。由于某种原因,编辑器没有显示内部异常。啊,是的,我知道这与此有关。那么我什么时候使用ldArg_0呢?太棒了,我又开始运行了@TomasPetricek一如既往地提供优质答案@sircodesalot我想如果您正在生成一个实例方法,并且希望调用
this.Foo(…)
,那么您需要
Ldarg\u 0
。在这种情况下,
Ldarg\u 0
this
引用放在堆栈上。