質問
VS2008を使用してATL COMオブジェクトを生成しましたが、コードには _MERGE_PROXYSTUB
という定義への参照が含まれています(最初にウィザードを実行したときに[プロキシ/スタブをマージ]オプションを選択したため) / p>
プロキシ/スタブのポイントは何ですか?マージオプションを選択しない場合、代わりに別の MyControlPS.DLL
が表示されます。これはいつ使用されますか?
FWIW _MERGE_PROXYSTUB
定義で囲まれたすべてのコードを削除すると、コントロールが登録され、正常に動作するように見えます。デバッグビルドは、 _MERGE_PROXYSTUB
を定義することさえしませんが、それでも正常に動作します。
では、プロキシ/スタブなしでも実行できますか?
解決
COMオブジェクトを、COMオブジェクトとは異なるスレッドモデルを使用するアプリケーションから呼び出すには、プロキシ/スタブが必要です。
たとえば、特定のスレッドモデルを使用するアプリケーションによってロードされるプラグインがありますが(覚えていない)、COMオブジェクトはマルチスレッドアパートメント(MTA)であるため、プロキシ/スタブが必要です関数呼び出しが行われたときにオブジェクト間でデータをマーシャリングする一方で、スレッドモデルのルールを維持します。
これらのルールが破られると、COMは例外をスローするか、 RPC_E_WRONG_THREAD
などの失敗HRESULTを返します。プロキシ/スタブのマージオプションをチェックしない場合、Visual Studioは、別のdllにビルドされるプロキシ/スタブ用の別のプロジェクトを生成します。これにより、必要な場合は展開が難しくなりますが、スレッドモデルの問題の影響を受けない場合は基本的に無視することができます。
COMオブジェクトを呼び出すアプリケーションがオブジェクトと同じスレッドモデルを使用している場合、プロキシ/スタブなしで実行できます
Larry Ostermanは、スレッドモデル彼のブログで。
他のヒント
また、インターフェイスにタイプライブラリフレンドリーなタイプ(BSTR、VARIANTなど)のみが含まれ、IDLのライブラリブロックに表示される場合、「タイプライブラリをマーシャリング」するように選択できます。つまり、システム提供のプロキシ/スタブはタイプライブラリのメタデータを使用します。
インターフェイスがライブラリブロック内に配置され、DllRegisterServerがカスタマイズされてタイプライブラリが登録されると(正しくリコールする場合、XxxModule :: DllRegisterServerにTRUEを渡す)、必要に応じて、システムによってインターフェイスがマーシャリングされますジョン・シブリー。
その時点では、プロキシ/スタブは使用されていないため、 _MERGE_PROXYSTUB
は効果がありません。