7

この質問をする前に、プロセス間通信用のライブラリと手法があることを明確にしておきたいと思います。ただし、これはCOMに関する学習用の質問です。アウトオブプロセスサーバーについても知っていますが、それは私が探しているものではありません。

質問:

私が知りたいのは、これがわからないので、可能であり、そうであれば、1つのプロセス(プロセスでインスタンス化されている)に存在するインプロセスCOMオブジェクト(DLLで定義されたオブジェクト)を共有することは可能ですか?別のプロセス全体?つまり、プロセスBのプロセスAからインプロセスオブジェクトへのポインタを取得するにはどうすればよいですか?

前もって感謝します。

4

3 に答える 3

10

はい、可能です。単一のプロセス内のアパートメント間で単一のオブジェクトインスタンスを共有している場合でも、別々のプロセス間で単一のオブジェクトインスタンスを共有している場合でも、基本的な原則は同じです。

ここには2つのアプローチがあります。おそらく最も簡単なのは実行中のオブジェクトテーブルを使用することです。これは基本的に、名前付きCOMオブジェクトのワークステーション全体のテーブルです。1つのプロセスで既知の名前のオブジェクトをテーブルに追加し、もう1つのプロセスでそのオブジェクトを検索します。

もう1つのアプローチは、マーシャリングを使用することです。マーシャリングは、COM APIを使用して、オブジェクトの場所を説明する一連のバイトを取得するプロセスです。次に、必要な手段(共有メモリ、ファイル、パイプなど)を使用して、その一連のバイトを別のプロセスにコピーし、受信プロセスで別のCOM APIを使用して、オブジェクトをアンマーシャリングできます。次に、COMは、元のプロキシと通信する適切なリモートプロキシをそのプロセスで作成します。詳細については、 APICoMarshalInterfaceおよびCoUnmarshalInterfaceを確認してください。

これらは両方とも、オブジェクトに対して適切なリモーティングサポートが必要であることに注意してください。使用しているインターフェースは、IDLで記述され、適切にコンパイルおよび登録されている必要があります。

-

残念ながら、これらのケースのどちらにも便利なコードはありません。

CoMarshalInterfaceアプローチの場合、プロセスは次のようになります。

  • CreateStreamOnHGlobal(NULL hglobalを使用)を使用して、COMが必要に応じて割り当てるHGLOBALに基づくIStreamを作成します
  • CoMarshalInterfaceを使用して、ストリームへのインターフェイスポインターをマーシャリングします(これにより、HGLOBALがバックアップするメモリに書き込みます)
  • GetHGlobalFromStreamを使用して、ストリームからHGLOBALを取得します
  • GlobalLock / GlobalSizeを使用してHGLOBALをロックし、マーラリングされたデータにアクセスします(完了したらGlobalUnlock)
  • バイトをターゲットプロセスにコピーする手段を使用します。

反対側では、次を使用します。

  • GlobalAlloc / GlobalLock / GlobalUnlockを使用して、新しいHGLOBALを作成し、マーシャリングされたデータを入力します
  • 新しいHGLOBALを使用してCreateStreamOnHGlobal
  • このストリームをCoUnmarshalInterfaceに渡します

通常のCOMおよびWindowsの参照/リソースルールは、これらすべてに適用されます。必要に応じてAddRef/Release。GlobalFreeを使用して、割り当てたHGLOBALなどを解放します。

于 2011-03-25T10:07:53.667 に答える
1

ウィンドウメッセージWM_GETOBJECTを使用した別の可能な解決策もあります。

オブジェクトを持つアプリケーションでは、独自のクラスでウィンドウを作成するだけです。ハンドラーでは、次のようにウィンドウメッセージを処理する必要があります(インターフェイスの例としてIDispatchを使用します)。

LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_GETOBJECT:
        {
            if(lParam == OBJID_NATIVEOM)
            {
                return LresultFromObject(IID_IDispatch, wParam, g_MyGlobalIDispatchPointer);
            }
            else
            {
                // Not handled
                break;
            }
        }
        return 0;
    }

    // Default
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

他のアプリケーションは、その特定のウィンドウを見つけて、 AccessibleObjectFromWindowを介してオブジェクトを取得する必要があります

例:

HWND hWndCommunicator = FindWindow(_T("MyWindowClassOfTheOtherApplication"), _T("MyWindowTitleOfTheOtherApplication"));
if(hWndCommunicator)
{
    IDispatch* poObject = nullptr;
    HRESULT hr = AccessibleObjectFromWindow(hWndCommunicator, static_cast<DWORD>(OBJID_NATIVEOM), IID_IDispatch, &poWindow);
    if(SUCCEEDED(hr))
    {
        // Do something with the object of the other process
        // i. e. poObject->Invoke
    }
}

マーシャリングは、このソリューションを使用して自動的に実行されます。

于 2016-11-11T10:36:33.573 に答える
0

それがCoRegisterClassObjectとCoGetClassObjectの目的です。

于 2011-03-24T22:33:22.127 に答える