【问题标题】:RTD - making the sample COM DLL into a COM exeRTD - 将示例 COM DLL 制作成 COM exe
【发布时间】:2009-02-14 05:34:12
【问题描述】:

我计划将我现有的应用程序变成RTD server

该应用程序目前是用 C++ 编写的,虽然我最终会将它移植到 C#/Mono,但我希望能够使用 C++ 添加 RTD 功能。

我找到了一些示例代码(MSVCRTDServer)和这个站点:http://weblogs.asp.net/kennykerr/archive/2008/10/29/excel-rtd-server-in-c.aspx

不幸的是,这些是 DLL,而且我很久以前就忘记了我所知道的所有 COM(告别)。

如何将 DLL 示例合并到 EXE 中?这显然是将 COM 服务器封装在 EXE 而不是 DLL 中。

编辑:

请注意,现有应用程序具有 MFC GUI。

编辑:

预期用途是运行现有的 GUI 应用程序 - 无需 COM/RTD 接口的客户端启动应用程序。 (虽然我不会否认那会很好)

基本上,我想用我自己的数据实现 IRTDServer 接口——以便 Excel(或其他应用程序)可以访问应用程序提供的动态数据。 (这是一个与串行端口设备对话的程序 - 该设备的状态/状态会发生变化,我希望能够异步更新客户端的变化)

所以,我需要创建一个 COM 对象并注册它,以便客户可以“看到”它。

我不确定如何将 COM 对象添加到 exe 并让该 COM 对象实现现有/预定义的接口。

编辑 我为此开始了赏金,所以我可以获得代码示例。显然,我太懒惰和愚蠢(或者可能只是对 COM 的过度厌恶),无法开始使用 Franci Penov 的现有答案。 (这非常有用,也是一个很好的开始)

所以基本上我正在寻找的是:

将我现有的基于对话框的 MFC 应用程序用于运行一堆线程并将其转换为 RTD 服务器(具有相同的 UI)的代码

所有的 cocreate 和 CoThisandthat 等等。我在哪里把这些代码放在我的 exe 中?如何扩展/实现 IRTD 的东西?

一个示例 MFC hello world 应用程序(基于对话框)的前后将得到公认的答案。

  1. 在应用程序之前包含 mfc 对话框应用程序的所有源代码。
  2. “after”应用程序基于步骤 #1 中的 MFC 应用程序,实现 RTD srver 接口及其所有源。 (所有项目文件、源代码等)
  3. 在 GUI/Visual Studio 中执行的步骤,以及从步骤 1 创建步骤 2 的其他步骤。 (创建了 IDL 等其他文件。)

理想情况下这是为 VS2008 提供的,但任何版本都可以使用。

谢谢。

【问题讨论】:

    标签: c++ com rtd


    【解决方案1】:

    编辑:老兄,自 2000 年以来我就没有接触过 MFC。我希望在我的余生中保持这种状态。 :-) 无论如何...

    显然,自上个世纪以来,巫师已经进化了。以下为 MFC 应用添加 ATL COM 支持的步骤适用于 VS 2008。

    1. 生成一个简单的基于 MFC 对话框的应用程序,称为 MFCTest。 不要选中向导中的自动化复选框。
    2. 右键单击项目并选择 Add / Class... 在对话框中,选择 ATL Simple Object。您将收到一条警告,指出将向项目添加 ATL 支持。
    3. 将打开一个新向导,其中包含新 ATL 对象的选项。

    你应该完成了。

    坦率地说,我认为没有任何理由在此处发布向导生成的代码。但是,如果您对该代码的特定部分还有其他问题,请将它们发布在 SO 上,我会为您提供帮助。


    编辑:这正在慢慢变成一篇文章。如果我们继续这样下去,我什至可能会出版一本书。 :-)

    一旦您将简单的 ATL 对象集成到 MFC 项目中,就可以向其中添加 RTD 接口。您需要从接口继承并将其添加到COM_INTERFACE_MAP。由于 RTD 接口是 IDispatch 接口,您必须从 IDispatchImpl 继承您的类,并使用 COM_INTERFACE_ENTRY2 将 IDispatch 添加到 COM_INTERFACE_MAP(以指定它是通过 IRtdServer 实现的。

    我不太熟悉 RTD 的工作原理。如果 Excel 需要订阅您的更新,您可能还需要 add support for COM connection points 上课。这里还有一个链接可以刷新您的connection points in ATL 知识。

    顺便说一句,我偶然发现了这篇带有C++ definitions of the two RTD interfaces 的博客文章。你可能已经有了它们,但为了完整起见,我想我会添加它。


    最简单的方法是通过VS向导创建新的ATL EXE项目,让它承担注册和流程管理部分。其余的并没有什么不同。

    如果您需要一个特定的样本来开始您的旅程,回到 COM 外的领域,您可以查看LABRADOR

    您可能更感兴趣的几个链接:

    编辑:如果您只需要知道如何在 EXE 中使用 COM 注册对象,以便客户端应用程序可以 CocreateInstance 它,请查看CoRegisterClassObject。然而:

    • 对象必须是 COM 对象
    • 你需要为它实现一个类工厂
    • 如果你想要进程管理(即 COM 按需启动你的应用程序),ClassID 需要在注册表中注册
    • 如果客户端要通过 ProgID 创建,ProgID 需要在注册表中注册
    • 如果您正在执行自定义编组,您可能需要自定义代理/存根 dll
    • 如果您的应用具有 UI,则必须修改关闭逻辑,以便当用户关闭 UI 时,应用不会退出,直到对您的对象的最后一个 COM 引用也被释放

    编辑 2:我仍然建议您查看 ATL 进程外示例以及 ATL 向导将生成的骨架以了解操作顺序。但是,您可能需要深入研究 ATL 代码以了解究竟发生了什么。

    这是该过程的简短版本:

    在启动时,应用程序需要检查特定的命令行参数 - /embedded。如果存在该参数,则表示应用程序正在由 COm 启动以响应 CoCO 调用。此时应用可能会选择不显示其 UI。

    无论应用是否显示 UI,它都必须为它通过上面提到的 CoRegisterClassObject API 提供的任何 COM 对象注册类工厂。

    如果应用程序是通过 COM 启动的,它可以选择在最后一个 COM 引用版本时自行关闭。 (这通常通过一个额外的全局引用计数器检测到,该计数器在任何对象 AddRef 上增加,在任何对象 Release 上减少)。但是,如果应用程序检测到用户与其 UI 交互,则它不应自行关闭。在这种情况下,关闭会延迟到用户明确关闭最后一个 UI(为了使检测更容易,应用程序通常在用户尝试明确启动它之前不会显示其 UI)

    如果应用程序由用户启动并且 las UI 已关闭,则应用程序应检查其中是否存在对其中任何对象的未完成的 COM 引用。如果没有,它可以自行关闭。但是,如果有 COM 引用,应用程序应该隐藏 UI,但会继续运行,直到最后一个引用被释放。

    如果应用程序已经到了将要关闭的点,它应该撤销所有类工厂注册。

    【讨论】:

    • 是的,从头开始可能更容易,但重点是我有一个现有的应用程序,它将作为数据的来源,我想将 RTD 代码硬塞到其中。 ..我会看看链接。谢谢
    • 感谢您提供更多信息。这可能足以让我继续前进。
    • 好的,再次感谢。巫师们创造的所有东西都让我头疼。现在我开始记起为什么我从来没有错过将 COM 抛在后面……
    • 我会试试 atl 向导。我只是不确定如何用我自己的实现/提供/扩展 RTD 接口。不知道它是如何工作的。
    【解决方案2】:

    您在 ATL Server 项目中编组您的代码。请参阅ATL Server Samples 上的示例。

    【讨论】:

    • ATL Server 用于使用 ATL 创建 ISAPI 扩展。它将需要 IIS 托管。它会起作用,但部署和配置解决方案会更加困难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 2011-07-27
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多