6

物事を監視する必要があるアウトプロセス COM サーバーがあります。このサーバーはサービスとして実行され、内部的にはシングルトンです。簡単にするために、私は彼を BossCom と呼びます。

ワーカーである別のアウトプロセス COM サーバーがあります。システムの安定性を確保するために、これは使い捨てサーバーです (つまり、2 つの WorkerCom を作成すると、2 つの WorkerCom.exe が実行されます)。簡単にするために、私は彼を WorkerCom と呼びます。

WorkerCom は、誰かが適切なコマンド ライン引数を指定してコマンド ライン経由で実行した場合でも、単独で起動することもできます。

全体的な目標は、BossCom が周りの WorkerCom を把握し、彼らが何をしているかを把握し、彼らに命令 (一時停止、停止、立ち上げなど) を与えることができるようにすることです。

これに関する私の最初の考えは、WorkerCom が起動するたびに、BossCom を CoCreateInstance し、BossCom->RegisterWorker(IUnknown me) を呼び出すだろうというものでした。次に、WorkerCom がシャットダウンしようとしているときに、BossCom->UnregisterWorker(IUnknown me) を呼び出します。BossCom は、IWorkerCom の IUnknown を QueryInterface し、コマンドを発行できる可能性があります。

これらすべての com オブジェクトが同じプロセス内にある場合はうまく機能しますが、そうではありません。GlobalInterfaceTable を使おうと思ったのですが、単一プロセスという意味でグローバルなだけです。

私はこれを調査するのに数日を費やしましたが、途方に暮れています。多分私は視野狭窄です。

Worker から Boss への com オブジェクトへの参照をマーシャリングするにはどうすればよいですか?

ああ、それと、BossCom は C# で書かれており、WorkerCom は ATL C++ で書かれていますが、VB、Scala、Lisp などで書かれたソリューションを使用します。核となるアイデアを翻訳できると思います。:-)

4

5 に答える 5

2

コメントによると、これは実際に箱から出して動作します。それが機能するようになりますが、もう1つの詳細があります。

もともと、インターフェイスのコピーを処理するC#インターフェイスを調べていたとき、引数の型はIntPtrでした。IntPtrは長いので、値をそのまま転送するため、機能しません。

重要なのは、引数にMarshalAs属性を設定することです。したがって、RegisterWorkerメソッドは次のようになります。

    public void RegisterWorker(
        [In, MarshalAs(UnmanagedType.IUnknown)] object ptr
        )
    {
        IWorkerCom worker = (IWorkerCom) ptr;
        Workers.Add(worker);
    }

本当に素晴らしい。

于 2011-01-14T18:07:26.683 に答える
2

異なるマシン間でも COM オブジェクト インスタンスを識別するために使用されるMonikersを確認する必要があります。

于 2011-01-14T14:47:57.320 に答える
1

最近、似たようなことをしなければならなかったのですが、共有メモリを使用すると非常にうまくいくことがわかりました。BossComは共有メモリを作成して所有でき、ワーカーは共有メモリにエントリを作成して登録できます。これが私が話していることへのMSDNリンクです。ミューテックスを使用して、メモリへのアクセスを同期することを忘れないでください...

于 2011-01-14T14:26:15.127 に答える
1

C# でマーシャリング可能なインターフェイスを作成するには、少し制限があります。プロキシをセットアップする簡単な方法はありません。ATL ではそのような問題はありません。IDL でコールバック インターフェイスを宣言してください。そして、RegisterWorker() 呼び出しでインスタンス ポインターを渡します。サーバーは、登録解除の呼び出しを受け取るまで、それを保存する必要があります。そのコールバック インターフェイスを使用して通知を生成します。

于 2011-01-14T14:46:19.870 に答える
1

ROT (Running Object Table) も調べる必要があります。これは、この問題を解決する別の方法である可能性があります。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms695276(v=vs.85).aspx

http://www.codeproject.com/KB/COM/ROTStuff.aspx

于 2011-10-28T16:38:06.260 に答える