【问题标题】:Out of process COM object dynamic versioning进程外 COM 对象动态版本控制
【发布时间】:2019-11-06 11:11:28
【问题描述】:

我正在使用由 myexe.exe 托管的进程外 COM 对象。托管 COM 对象的这些 exe 有多个版本。每个版本的接口和方法都可以略有改变。每个 myexe.exe 文件都位于版本化文件夹中(例如 C:\v2\myexe.exe、c:\v3\myexe.exe)

无法提前知道哪些版本将运行。我的客户端应用程序使用 ROT 附加到正在运行的 exe。我需要能够动态使用该 COM 对象版本,通过 IUnknown.QueryInterface 发现接口。

不幸的是,如果在 Windows 注册表中注册了旧版本的 COM,我在使用新方法时会崩溃。一旦我使用“myexe.exe -regserver”在 Windows 注册表中注册了较新版本的进程外 COM,崩溃就会消失。所以我不能在运行时动态使用旧版本或新版本的 meexe.exe,因为每次我需要重新注册我的 com 版本。

关于我为什么会崩溃或如何解决问题的任何想法?

【问题讨论】:

  • 您的意思是您使用的是具有不同界面定义/布局的相同界面 ID (IID)?
  • 是的。我不想依赖界面的 Windows 注册表定义。我想像这篇文章一样动态调用它:forums.codeguru.com/…
  • 不确定您在做什么/正在寻找什么。您在其他人的 cmets 中谈论 IDispatch。你应该解释得更好。可以肯定的一件事是,您不能在不更改 IID 的情况下更改 IUnknown 派生接口(“早期绑定”)。这是一个刻在石头上的二元合约。

标签: c++ com running-object-table


【解决方案1】:

COM 接口从不版本化。每个 COM 接口都与其他任何接口一样不同。 您使用 IID 来区分并使用 QueryInterface() 从一个到另一个。

请参阅QueryInterface 指南和Guide

【讨论】:

  • 是的,但不同版本的软件在同一界面中添加了更多方法。对不起,这不是我的错。它是由该软件的开发人员完成的。我知道正确的指导方针永远不会对它们进行版本化,而是引入新的接口,如 Interface2 或 Interface3 等。我只需要解决问题,因为我正在为原始有缺陷的 COM 服务器开发客户端。
  • 你什么也做不了。它将是接口的不同虚拟表。 COM 接口是虚拟的,如果 vtbl 发生更改并且您没有更新的声明,您将遇到崩溃。
  • 应该有我希望的方法。更正:因为它是进程外 com,所以我在使用 IUnknown->QueryInterface 后使用动态 IDispatch 调用。
  • 如果它是 IDispatch,那么如果依赖类型库进行自动 Invoke 调用,您仍然会遇到问题。否则你必须手动调用 Invoke()。
【解决方案2】:

COM 接口是不可变的。一旦你定义了一个接口并开始在你的应用程序中使用它,你就不能再改变它了。它的 IID 和 VTABLE 被锁定。如果您需要对现有方法进行更改或添加新方法,您必须为此目的创建一个具有新 IID 的新接口(新接口可以从以前的接口派生,尽管这是不需要)。然后服务器必须实现新接口,客户端可以在需要时QueryInterface() 服务器获取新接口。没有办法解决这个问题,这是 COM 的基本规则,以免在创建新的服务器版本时破坏现有客户端。

【讨论】:

    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 2017-03-22
    • 2011-01-22
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2011-02-07
    • 2010-12-13
    相关资源
    最近更新 更多