【问题标题】:Create each COM-instance in it's own exe-container在它自己的 exe 容器中创建每个 COM 实例
【发布时间】:2013-04-04 07:55:58
【问题描述】:

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

我想需要一些背景知识。

我们有一个最终用户客户端,它的核心逻辑组件位于单例 COM 对象中。 (不是propper单例,但它在内部使用全局变量,所以它会失败。)所以每个exe文件应该只有一个实例。做客户的同时方便。

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

问候 雷夫

【问题讨论】:

    标签: com


    【解决方案1】:

    这几天我一直在努力解决这个问题。我终于找到了一个可行的解决方案。我的 COM 对象是使用 ATL 编写的,所以我的代码 sn-p 将面向此,但技术解决方案应该是明确的。这一切都取决于如何注册类对象。 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 时 它以对象类结束。

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

    【讨论】:

    • return CAtlExeModuleT::RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SUSPENDED | REGCLS_SINGLEUSE);
    【解决方案2】:

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

    我自己从未尝试过,我不知道您是否可以为工厂指定标志(控制代理是否可以用于多个对象),但也许您可以通过 DCOMCNFG 或OLEVIEW。

    【讨论】:

    • 这个解决方案不是让所有实例都驻留在一个 DLLHOST 进程中吗?而是每个实例都有自己的私有进程?
    • 这就是我所说的类工厂的意思。当工厂在进程外服务器中注册时,您可以指定是否要多次响应 CoCreateInstance——如果没有,将启动一个新服务器。见msdn.microsoft.com/en-us/library/ms679697(VS.85).aspx。你想要 REGCLS_SINGLEUSE。问题是您是否可以向 DLLHOST 指定要使用的 REGCLS...我不确定。
    • 啊,听起来很有趣。这次我通过变通方法解决了它。但“下一次”我应该多看这个。谢谢!
    【解决方案3】:

    我的 COM 时代已经一去不复返了,但据我所知,没有内置的方法可以做到这一点。

    重写代码使其支持多个实例可能比使用 COM 采用每个实例一个进程的路由更容易,但您可以这样做:

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

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

    【讨论】:

    • 好建议。在以“proper”方式进行操作之前,我希望能多一点“魔法钥匙”。
    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多