0

さまざまな理由 (信頼性、展開) のために別の AppDomain で実行する必要がある .NET コードがあります。現在の AppDomain に読み込まれないように、呼び出しを実際のものに委任する MBR から派生したプロキシ オブジェクトを作成しました。通常の CreateInstanceAndUnwrap でプロキシを作成します。

this.eDirectCommunication = (EDirectCommunicationProxy) this.appDomain.CreateInstanceAndUnwrap(x, y);

これは、.NET クライアントから使用するとうまく機能しますが、COM クライアントからロードするとキャストが失敗します。透過プロキシからのキャストに失敗します。必要なタイプが目的の AppDomain で作成され、Unwrap が成功することを検証しましたが、キャストは失敗します。興味深いことに、両方の AppDomain が同じベース ディレクトリを持っている場合に機能しますが、これはアセンブリ バインディングの失敗を示しています。しかし、Fusion のログ ビューアーには問題はありません。

ここここに似たような質問が 2 つありますが、答えはありません。何がうまくいかないのか、またはどうすればさらにデバッグできますか?

4

1 に答える 1

1

私は数年前にこの正確な問題に遭遇しました。IIRC の問題は、コール スタックが 2 つのアプリ ドメインの境界を越えることでした。これにより、マネージ オブジェクトへのプロキシが 2 回マーシャリングされます (COM->default->yours:new object:->yours->default)。通常は問題ありませんが、.NET COM マーシャラー QI が「こんにちは、私はマネージ オブジェクトであり、特別なマーシャリング動作が必要です」と言う特別なインターフェイスがあります (申し訳ありませんが、IID を覚えていません。ComTrace を試すか、 IDispatch impl を所有し、CLR を介してマーシャリングして確認します)。これはあなたがうんざりしているところです-これがデフォルトドメインで実行されると、あなたが管理されていることがわかり、管理されたタイプを要求してロードしようとします。これは、新しいドメインの basedir がデフォルトと同じ場合にのみ成功します. これは明らかに目的全体を無効にします。

私がこれに対処した方法はいくつかあります。1 つの方法は、オブジェクトの作成を非同期にすることです。これにより、マネージ プロキシを新しいドメインからアンマネージ コードに直接プッシュできます (たとえば、アンマネージ コールバックを登録し、デフォルト ドメインをバイパスして新しいドメインから直接呼び出します)。これは、すべてをエンド ツー エンドで制御できないアドイン シナリオでは明らかに注意が必要です。

もう 1 つは、.NET マーシャラーが「本当にマネージド オブジェクトですか?」と尋ねたときに応答しなかった、ダム プロキシをロールするアンマネージド コードの小さなスライスを用意することでした。しかし、他のすべての QI と IDispatch のすべてを問題なく通過します (ハックも IDispatch のみに制限したため、はるかに簡単になりました)。したがって、新しいシーケンスは次のようになります: COM->default->yours:new object->new proxy wrapper->default->COM.

重要な PITA - 当時、CLR 相互運用チームの担当者からのブログ投稿を見つけました。これは、将来の CLR リリースでこれに対する修正の可能性を浮かび上がらせていましたが、それは数年前のことであり、誰だったか覚えていません (申し訳ありませんが、私はもう生計を立てるために相互運用をしません、よかったです!)

于 2009-09-28T12:00:39.057 に答える