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

问题描述 投票:2回答:3

是否可以在自己的专用主机进程中创建COM实例?

我想需要一些背景。

我们有一个最终用户客户端,该客户端在单例COM对象中具有中央逻辑组件。 (不是适当的单例,而是在内部使用全局变量,因此将失败。)因此,每个exe文件应该只有一个实例。 结交客户时很方便。

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

问候雷夫

com
3个回答
2
投票

我的COM日子早已一去不复返了,但据我所记得,没有内置的方法可以做到这一点。

重新编写代码,使其支持多个实例可能比使用COM进行每个实例一个进程的路由更容易,但是您可以执行以下操作:

  • 将线程局部存储用于全局变量,并编写另一个CoClass,每个实例拥有自己的线程,通过该线程可以对使用全局变量的类的访问进行编组。 这至少可以使您避免DCOM对性能的影响。

  • 编写您自己的进程外exe服务器(类似于Windows的DllHost.exe)来承载您的COM实例。 这需要IPC(进程间通信),因此您要么自己编写一些代码,以编组对外部进程的调用,要么使用DCOM(假定您的COM对象实现了IDispatch)


2
投票

这个其他问题提到了如何使用DLLHost作为替代过程的描述: http : //support.microsoft.com/kb/198891

我自己从未尝试过,而且我不为人所知,如果您可以为工厂指定标志(该标志可以控制替代对象是否可用于多个对象),但是也许可以通过DCOMCNFG或OLEVIEW进行调整。


1
投票

我已经为这个问题苦苦挣扎了几天。 我终于找到了可行的解决方案。 我的COM对象是使用ATL编写的,因此我的代码段将针对该对象,但是技术解决方案应该清楚。 所有这些都取决于类对象如何注册。 REGCLS_SINGLEUSE标志是关键。 现在,每个对象实例都有单独的进程。

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

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

从MSDN关于REGCLS_SINGLEUSE

REGCLS_SINGLEUSE

使用CoGetClassObject将应用程序连接到类对象之后,该类对象将从公共视图中删除,以便其他任何应用程序都无法连接到该对象。 此值通常用于单文档界面(SDI)应用程序。 指定此值不会影响对象应用程序调用CoRevokeClassObject的责任; 完成对象类后,它必须始终调用CoRevokeClassObject。

我的理论是,由于注册已从公众视野中删除,因此导致为后续实例创建一个新过程。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.