動的に放出されたアセンブリの主な例外を得るにはどうすればよいですか。 -- reflection フィールド と f# フィールド 関連 問題

How do I get a meaninful exception from a dynamically emitted assembly?












3
vote

問題

日本語

Emit Errorsのデバッグを試みることは、例外の詳細について詳しく説明するための簡単な方法があります 発行されたコードによって引き起こされますか?

たとえば、このコードで: <事前> <コード> SubscribableEditions8

GET "Exceptionが呼び出しのターゲットによってスローされました。、 SubscribableEditions9 を2行目から最後の行に電話しようとしています。エミッティングコードは常に問題がありますが、それほど問題があるかもしれません意味のある例外を得る方法を理解することができれば痛みを伴う。考え?

英語

Trying to debug emit errors, is there a simple way to find out more information about exceptions c caused by emitted code?

For example, with this code:

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 

I get "Exception has been thrown by the target of an invocation., when I try to call Invoke on the second to last line. Emitting code has always been problematic, but it might be less painful if I could figure out how to get meaningful exceptions. Thoughts?

</div
     
     
     

回答リスト

5
 
vote
vote
ベストアンサー
 

は無駄な例外を得ることは、ILコードを生成する喜びの一部です。 「呼び出しのターゲットから例外がスローされた」と表示されたら、 InnerException プロパティを見ることができ、あなたがそこで何か便利な何かを得ることができるかどうかを確認することができます:

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

この場合、内部例外は次のとおりです。

System.InvalidProgamexception:共通言語ランタイムが無効なプログラムを検出しました。

これは単にあなたの生成されたILが間違っていることを意味します - 私はより良いエラーメッセージを受けることはありませんが、生成されたアセンストをディスクに保存して peverify または反射演算を実行することはできません。生成されたコードをどのように解釈するかを見るためには、IlSpy。これは、適切な(動的)アセンブリを生成するための別のコードパスを追加する必要があることを意味しますが、それは価値があると思います - 生成されたILを頻繁にデバッグする必要がある...

この場合、 Ldarg_0 this (最初の引数ではなく)を指しますので、

を生成する必要があります。 <事前> <コード> ilGen.Emit(OpCodes.Ldarg_1) ilGen.Emit(OpCodes.Ldarg_2) ilGen.Emit(OpCodes.Add) ilGen.Emit(OpCodes.Ret)
 

Getting useless exceptions is a part of the joy of generating IL code. When you get "Exception has been thrown by the target of an invocation", you can look at the InnerException property and see if you can get something more useful there:

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

In this case, the inner exception says:

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

This simply means that your generated IL is wrong - I'm afraid you won't get a better error message, but you can save the generated assembly to a disk and run peverify or Reflector/ILSpy to see how they would interpret the generated code. This means you'll need to add another code path to generate a proper (non-dynamic) assembly, but I think it is worth it - you'll need to debug the generated IL often...

In this case, the problem is that Ldarg_0 refers to this (rather than the first argument) and so you need to generate:

ilGen.Emit(OpCodes.Ldarg_1) ilGen.Emit(OpCodes.Ldarg_2) ilGen.Emit(OpCodes.Add) ilGen.Emit(OpCodes.Ret) 
</div
 
 
       
       

関連する質問

0  Don Syme F#3Dパラボラでローリングしているサッカーボールのデモ  ( Don syme f demo of soccer balls rolling in a 3d parabola ) 
誰かがDon Syme F#デモを示すDEMO SACH BALLSが3Dパラボラで転がりますか? ...

3  F#もう1つのリスト?  ( F one list to another ) 
タプルに3つの値を持つタプルのリストがあります 前のリストから、タプルから1つの値を指定して弦の新しいリストを作成したい。 <事前> <コード> List [(string * string * int) ] List[ for i in columns -...

1  f#オペレータの解像度  ( F operator resolution ) 
私はベクトルと呼ばれるクラスを持っています。ベクトルは、ベクトルから継承するDenseVector、Sparsevectorなどのクラスによってもサブタイプ化されています。次のを書くときにf# <事前> <コード> let foo (v : #Vector) ...

10  F#コードの生成  ( Generating f code ) 
T4は、C#/ vb.netの「公式」コード生成エンジンです。しかし、 f#はそれをサポートしていません(これは4月からですが、私はできませんでした)新しい言及を見つけました。だからF#コードを生成するための良い方法は何ですか? 編集: 実装したい 2-3指...

2  YouTube APIからPlayListMemberオブジェクトの構築エラー - C#OK F#エラー  ( Error constructing playlistmember object from youtube api c sharp ok f error ) 
http://code.google.com/p/google-gdata/downloads/detail?name=youtube_sdk_1.8.0.0.msi f#インタラクティブバージョン4.0.40219.1私は単にPlayList1be...

10  f#でオプションの種類はどのように機能しますか  ( How does the option type work in f ) 
だから私は謝罪のF#のreptを読んで、おもちゃISH F#ライブラリを構築するときにそれを参照として使用していますが、私が把握できなかったこととそれが「オプション」タイプです。< / P> どのように機能していますか、それは現実の世界の使用量ですか? ...

1  F#テンプレートエンジンと同様に、Mako?  ( F templating engine similar to say mako ) 
は1つが存在しますか? 私が見つけた最も近いです - https://github.com/antaris/razorengine ;しかし、私はそれによって溢れていません(特に私はそれを仕事に入れることができません。) ...

103  現実の世界で機能的なプログラミングをどのように使用できますか? [閉まっている]  ( How can i use functional programming in the real world ) 
閉鎖。この質問はもっと焦点を絞ったにする必要があります。現在答えを受け付けていません。 この質問を改善したいですか? ...

37  普通のタスクでasync.awitask(タスク<t>ではありません)  ( How to async awaittask on plain task not taskt ) 
F#のC#ライブラリを消費しようとしています。ライブラリは非同期/待ち合わせを重視します。 <コード> async { ... } ワークフロー内でF#。内で使用したいです。 private final int direction; private bo...

101  HASKELL構成(。)VS#のパイプフォワードオペレーター(|>)  ( Haskell composition vs fs pipe forward operator ) 
f#では、パイプフォワードオペレータの使用、<コード> 9988766610 はかなり一般的です。しかし、Haskellでは、 998877611 を使用した機能構成を見たことがあります。私は関連であることを理解しています。パイプフォワードがHaskellで...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有