是否有可能在它自己的专用主机进程中创建一个COM实例?
我想需要一些背景知识。
我们有一个最终用户客户端,它在单例COM对象中包含它的中心逻辑组件。 (不是propper单例,但它在内部使用全局变量,因此它会失败。)因此每个exe文件应该只有一个实例。方便客户制作。
但是,我现在应该制作一个“客户端模拟器”来测试服务器端。因此,我做了20个客户端组件的实例。 如果我可以使每个实例在其自己的exe-host中实例化,那么将处理单例问题。
此致 雷夫
答案 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 它完成了一个对象类。
我的理论是,由于注册已从公共视图中删除,因此会导致为后续实例创建新进程。