在它自己的exe容器中创建每个COM实例

时间:2009-08-17 10:43:55

标签: com

是否有可能在它自己的专用主机进程中创建一个COM实例?

我想需要一些背景知识。

我们有一个最终用户客户端,它在单例COM对象中包含它的中心逻辑组件。 (不是propper单例,但它在内部使用全局变量,因此它会失败。)因此每个exe文件应该只有一个实例。方便客户制作。

但是,我现在应该制作一个“客户端模拟器”来测试服务器端。因此,我做了20个客户端组件的实例。 如果我可以使每个实例在其自己的exe-host中实例化,那么将处理单例问题。

此致 雷夫

3 个答案:

答案 0 :(得分:2)

我的COM时代早已过去,但据我记忆,没有内置的方法可以做到这一点。

重写代码可能更容易,因此它支持多个实例,而不是使用COM进行每个实例的一个进程路由,但这是你可以做的:

  • 为全局变量使用线程局部存储并编写另一个CoClass,其中每个实例拥有自己的线程,通过该线程对包含全局变量的类的访问进行封送处理。这至少可以让您避免DCOM对性能的影响。

  • 编写您自己的进程外exe服务器(类似于Windows的DllHost.exe)来托管您的COM实例。这需要IPC(进程间通信),因此您必须自己编写代码来调用外部进程或使用DCOM(假设您的COM对象实现IDispatch)

答案 1 :(得分:2)

This other question提到了如何使用DLLHost作为代理进程的说明: http://support.microsoft.com/kb/198891

我自己从来没有试过这个,如果你可以为工厂指定标志(控制代理人是否可以重复用于多个对象),我不知道副手,但也许你可以通过DCOMCNFG或OLEVIEW。

答案 2 :(得分:1)

我几天来一直在努力解决这个问题。我终于找到了一个有效的解决方案。我的COM对象是使用ATL编写的,所以我的代码片段将面向它,但技术解决方案应该是清楚的。这一切都取决于类对象的注册方式。 REGCLS_SINGLEUSE 标志是关键。我现在为每个对象实例都有单独的进程。

在ATL模块中,重写RegisterClassObjects()函数,如下所示:

HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags) throw()
{
    return base::RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SUSPENDED | REGCLS_SINGLEUSE);
}

关于 REGCLS_SINGLEUSE :来自MSDN:

  

<强> REGCLS_SINGLEUSE

     

应用程序连接到类对象后   CoGetClassObject,类对象从公共视图中删除,以便   没有其他应用程序可以连接到它。通常使用此值   用于单文档界面(SDI)应用程序。指定这个   value不会影响对象应用程序的责任   调用CoRevokeClassObject;它必须始终调用CoRevokeClassObject   它完成了一个对象类。

我的理论是,由于注册已从公共视图中删除,因此会导致为后续实例创建新进程。