Reverse P/Invoke and exception
昔、@IT会議室で「マネージデリゲートをコールバック関数としてアンマネージコードに渡してるんだけど、これってガベージコレクタされないの?」って議論があったのを思い出した。
以下は訳。誤訳たっぷりと思われるので、できれば本文を参照してほしい。
P/Invoke とは、マネージコードがネイティブの関数ポインタを実行する事だ。そして、リバース P/Invoke とは、ネイティブコードがマネージのデリゲートを関数ポインタとして実行する事で、大概はコールバックとなる。
ネイティブコードがマネージのデリゲート関数ポインタを実行したとき、実際には CLR thunk を呼んでいる。thunk は AppDomain transition から真のAppDomain に移行し、デリゲートを実行する。コールバックでマネージのデリゲートが未処理例外をスローしたら、AppDomain transition でコンテキストをまたがった例外として発生するだろう。きっと、ワトソン博士のエラーレポートも。
ワトソン博士が嫌いなら、以下の二つの事ができる。
1).マネージコードのトップレベルで try/catch ブロックを書いて、例外を全部捕まえる。はいはい、ネイティブコードにエラーを伝えるために若干のメカニズムが必要だよ。マネージデリゲートが、戻り値か out パラメータの一つに HRESULT を返すようにするんだ。
2).ICLRRuntimeHost::ExecuteInAppDomain を使う。そうすれば、CLR はどんな未処理例外でも HRESULT として呼び出し元に返す。