如何跨进程边界编组进程外COM引用?

时间:2011-01-14 14:18:38

标签: c# c++ com interprocess

我有一个需要关注事物的进程外COM服务器。此服务器作为服务运行,并且在内部是单例。为简单起见,我会称他为BossCom。

我有另一个进程外COM服务器,它是一个工作者。对于系统稳定性而言,它是一次性服务器(意味着如果您创建2个WorkerCom,则有2个WorkerCom.exe正在运行)。为简单起见,我会称他为WorkerCom。

WorkerCom可以通过任何东西启动,即使有人通过命令行使用正确的命令行参数运行它也可以自己启动。

总体目标是让BossCom知道WorkerComs是什么,知道他们在做什么,并能够给他们订单(暂停,停止,加速等)。

我最初的想法是,每当WorkerCom启动时,他都会CoCreateInstance一个BossCom并调用BossCom-> RegisterWorker(IUnknown me)。然后当WorkerCom即将关闭时,他会打电话给BossCom-> UnregisterWorker(IUnknown me)。 BossCom可以为IWorkerCom查询IUnknown,并能够发出命令。

如果所有这些com对象都在同一个进程中,那将会很有效,但事实并非如此。我想过使用GlobalInterfaceTable,但它只是一个单一过程意义上的全局。

我花了几天时间研究这个并且不知所措。也许我是隧道视野。

如何编组从工人到老板的com对象的引用?

哦,而且,对于它的价值,BossCom是用C#编写的,而WorkerCom是用ATL C ++编写的,但我会用VB,Scala,Lisp或其他任何东西编写解决方案。我想我可以翻译核心理念。 : - )

5 个答案:

答案 0 :(得分:2)

您应该查看Monikers,用于识别COM对象实例,甚至跨越不同的计算机。

答案 1 :(得分:2)

根据评论,这确实是开箱即用的。有一个额外的细节,但它使它工作。

最初当我在查看处理复制接口的C#接口时,参数类型是IntPtr。好吧,IntPtr只是一个很长的时间,所以它按原样传输值,因此不起作用。

关键是在参数上设置MarshalAs属性。所以我的RegisterWorker方法如下所示:

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

非常棒。

答案 2 :(得分:1)

最近我不得不做类似的事情,发现使用共享内存对我来说非常好。 BossCom可以创建和拥有共享内存,工作人员可以通过在共享内存中输入来注册。这是我所说的MSDN link。请记住使用互斥锁来同步对内存的访问...

答案 3 :(得分:1)

您在C#中创建可编组接口的能力有限。没有简单的方法来设置代理。在ATL中没有这样的问题,在IDL中声明一个回调接口。并使用RegisterWorker()调用传递实例指针。服务器应该存储它,直到它获得取消注册。使用该回调接口生成通知。

答案 4 :(得分:0)

您还应该查看ROT(运行对象表),它可能是解决此问题的另一种方法。

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

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

相关问题