我计划将我现有的应用程序变成 RTD服务器.

该应用程序目前是用 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)

所有这些共同创造和 CoThisandthat 等等。我将该代码放在 exe 中的什么位置?我如何扩展/实施 IRTD 内容?

示例 MFC hello world 应用程序(基于对话框)的前后将获得可接受的答案。

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

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

谢谢。

有帮助吗?

解决方案

编辑: 老兄,从2000年开始我就没有接触过MFC了。我希望余生都能保持这种状态。:-) 反正...

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

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

你应该完成了。

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


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

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

我不太熟悉 RTD 的工作原理。您可能还需要 添加对 COM 连接点的支持 如果 Excel 需要订阅您的更新,请发送至您的班级。这里还有一个链接可以刷新您的 ATL 中的连接点 知识。

顺便说一句,我偶然发现了这篇博客文章,其中包含 两个 RTD 接口的 C++ 定义. 。您可能已经有了它们,但我想为了完整起见我应该添加它。


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

如果您需要特定示例来快速启动返回 COM 进程外领域的旅程,您可以查看 拉布拉多犬.

您可能进一步感兴趣的几个链接:

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

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

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

这是该过程的简短版本:

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

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

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

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

如果应用程序已达到将关闭的程度,则应撤销所有类工厂注册。

其他提示

您将代码编组到 ATL Server 项目中。样品见 ATL 服务器示例 .

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top