2

我正计划将我现有的应用程序变成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)

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

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

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

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

谢谢。

4

2 回答 2

3

编辑:伙计,自 2000 年以来我没有接触过 MFC。我希望在我的余生中保持这种状态。:-) 反正...

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

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

你应该完成了。

坦率地说,我看不出有任何理由在这里发布向导生成的代码。但是,如果您对该代码的特定部分还有其他问题,请将它们发布在 SO 上,我会帮助您。


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

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

我不太熟悉 RTD 的工作原理。如果 Excel 需要订阅您的更新,您可能还必须为您的类添加对 COM 连接点的支持。这里还有一个链接,用于刷新您在 ATL知识中的连接点。

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


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

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

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

编辑:如果您只需要知道如何使用 COM 在 EXE 中注册对象,以便客户端应用程序可以 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,但会继续运行,直到最后一个引用被释放。

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

于 2009-02-14T06:32:02.547 回答
0

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

于 2009-02-15T23:14:21.867 回答