为什么COM接口为相同的调用方法返回不同的值?

时间:2017-04-03 17:44:17

标签: com

当我在返回另一个接口的COM接口上调用方法时,punkVal每次都不同。

然而,如果我使用旧的punkVal调用接口方法,它也可以工作。看起来很多不必要的对象(或者可能是对象的指针)正在被创建,但我需要一定来确定返回的接口是否是唯一的。我所知道的是我调用的是返回一个接口(punkVal),每个实例的值都不同。该值指向的值始终相同,但我认为这是因为它指向vtable或其他东西,似乎不是一个可靠的检查。那个,甚至看似不同的界面实际上都是同一个界面。

要明确:

someCOMInterface foo();

我在foo上调用invoke并期望punkVal是someCOMInterface,我必须稍后在查询时使用invoke调用它的方法。但每次调用第一次调用时,我都会得到一个不同的someCOMInterface(调用返回的值中的“相同”但“不同”)。

1 个答案:

答案 0 :(得分:1)

这并不常见。完全由COM库的开发人员决定,对同一方法的多次调用返回的接口指针是否会返回相同的指针。

可能返回不同指针的原因之一是特定COM库中使用的核心对象模型可能不是COM。例如,我使用像shared_ptr之类的东西在C ++中编写了对象模型,这可以为C ++客户端提供更好的对象模型。但是当我公开我的C ++对象模型以实现互操作性时(或者更常见的是,将其暴露为DLL),COM通常是更好的选择。由于保持复杂的分层对象模型与一组包装类同步可能很困难,因此包装器对象可能只是临时的 - 必要时创建并在客户端不再使用它们时销毁。

在这些情况下,客户可能仍然需要知道对象是否相等" - 可以考虑包裹相同内部对象的两个不同对象"相等。"为了确定这一点,Microsoft定义了IObjectEquality接口。这个接口可以由COM包装器类实现,这样客户端就可以明确地检查两个不等的指针在概念上是否相等"对象。您正在使用的对象可能会也可能不会实现此接口。 This blog post显示了使用此接口确定对象相等性的完整示例。

如果未实现IObjectEquality,则由COM对象的开发人员提供一些做出此类决定的方法,通常是通过提供某种NameID或其他识别财产。例如,Excel的Application.Range属性将返回具有相同参数的后续调用的不同指针。要确定两个范围是否相等,您可以使用Range.Address方法获取"标识符"该范围,然后比较这些标识符。