RTD - 将示例COM DLL转换为COM exe

时间:2009-02-14 05:34:13

标签: c++ com rtd

我打算将现有的应用程序变成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对象实现现有的/预定义的接口。

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

基本上我正在寻找的是:

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

所有那些共同创造和CoThisandthat等等。我在那里把代码放在我的exe中?如何扩展/实施IRTD?

示例MFC hello world app(基于对话框)之前和之后将获得接受的答案。

  1. 在应用程序之前使用mfc对话框应用程序的所有源代码。
  2. “之后”应用程序基于步骤#1中的MFC应用程序,它实现了RTD srver接口及其所有源代码。 (所有项目文件,来源等)
  3. 在GUI / visual studio中采取的步骤,否则从步骤1创建步骤2。 (IDL等创建的其他文件。)
  4. 理想情况下,这是为VS2008提供的,但任何版本都可以使用。

    感谢。

2 个答案:

答案 0 :(得分:3)

编辑:老兄,我从2000年开始就没有碰过MFC。我希望能够在我的余生中保持这种状态。 :-)无论如何......

很明显,这些巫师自上个世纪以来一直在进化。以下步骤为VS 2008添加ATL COM支持和MFC应用程序。

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

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


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

    在MFC项目中集成简单的ATL对象后,可以向其添加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项目,并让它采用注册和流程管理部分。其余的并没有那么不同。

    如果您需要一个特定的样本来快速启动您的旅程,那么您可以查看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,但继续运行直到最后一个引用被释放。

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

答案 1 :(得分:0)

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