12

COM サーバー (C++/STA (MFC ベースのアプリ)) と COM クライアント (C#/MTA) があります。COM サーバーは MFC アプリであるため、STA 内に存在する必要があります (この件については選択の余地がありません)。クライアントはサーバーに呼び出しを発行し、サーバーはクライアントにコールバックを発行します。ここでエラーが発生します ( RPC_E_CANTCALLOUT_ININPUTSYNCCALL)。サーバーが MTA であった場合、この問題は発生しなかったと思いますが、残念ながら、MFC のドキュメントではアパートメントを MTA として初期化することを明示的に否定しています。

この問題を回避する方法についてのアイデアはありますか?

サーバー オブジェクト (実行中のオブジェクト テーブルを介して公開するオブジェクト) を独自のアパートメント (MTA) に配置するというアイデアをいじっています。これは良い考えでしょうか、それとも最初に試すのに簡単なものはありますか?

アップデート

サーバー オブジェクトは、アプリケーション内の特定の機能を指すシン インターフェイスにすぎません。ほとんどの場合、メモリ ロケーションの読み取りと書き込みを行うだけですが、アプリケーション内のさまざまなウィンドウにウィンドウ メッセージを生成する場合があります。サーバー オブジェクト自体はアプリケーション全体ではありません。

4

3 に答える 3

18

RPC_E_CANTCALLOUT_ININPUTSYNCCALLは、を介して送信されたWindowsメッセージに対して、ハンドラー内からマーシャリングされたCOM呼び出しを行おうとしたことを意味しますSendMessage。これは、特定のデッドロック状況を回避するのに役立ちます。「SendMessageハンドラーでのCOM呼び出しを回避する」というオプションがいくつかあります。

  • PostMessage自分自身へのメッセージをキューに入れるために使用でき、その投稿されたメッセージハンドラーで、COMコールバックを呼び出します。
  • 非同期DCOMを使用して、メッセージハンドラー内からの呼び出しの結果がブロックされないようにすることができます。
  • コールバックインターフェイスをマーシャリングしてから、スレッドプールワークアイテムから呼び出すことができます。これはメインアプリケーションのメッセージループから独立しているため、SendMessage呼び出しには含まれず、MTAに含まれることもあります。
  • MFC COMサポートを放棄して、別のスレッドから直接CoRegisterClassObjectを呼び出すことができます。つまり、サーバーのCOMオブジェクトへの呼び出しは、MFC UIスレッドからではなく、COMスレッドプールから(または、STAスレッドを使用している場合はそのスレッドから)呼び出されるため、通信にはWindowsメッセージを使用する必要があります。スレッド間; ただし、クライアントに同期呼び出しを行う必要がある場合は、それが最善のアプローチである可能性があります。
于 2011-07-07T19:39:41.350 に答える
2

クライアントから呼び出されたときに、アプリ内の STA コンテキストから自分自身を削除することはできません。MTA でサーバー オブジェクトをホストするかどうかは問題ではなく、COM の法則に従う必要がありますこの場合、STA は本当に厄介な「矯正施設」です。苦労してる…

これは私をかなり醜い道に導きましたが、うまくいきます。クライアントとの通信に COM を使用する代わりに、サーバー オブジェクトとコールバック参照をホストする MTA への独自の通信パスを手動で作成しています。私は基本的に、MTA スレッドが取得してクライアントに配信する呼び出しキュー (送信するパラメーターを含む STL コンテナー) を設定して、独自のマーシャリング コードを作成しています。その後、最初の呼び出しに応答しているコードに応答が返されます。同期は、Win32 イベント オブジェクトを使用して行われます。

幸いなことに、私がカバーしなければならないコールバックは多くありません。メカニズムの性質は静的であり、私自身の目的にのみ使用されます (実稼働環境では実行されません)。

ふぅ…大工になっていたら、どんな人生だったのだろうと思うことがあります。

于 2011-07-07T19:29:37.680 に答える
0

メッセージを受け取ったときにタイマーを作成し、COM 呼び出しを実行して、WM_TIMER の下の TimerProc/WinProc でさらに処理することができます。これは私にとってはうまくいきます。

于 2016-07-24T05:31:18.707 に答える