简体   繁体   English

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

[英]Why does COM interface return different values for same invoking method?

When I invoke a method on a COM interface that returns another interface, the punkVal is different each time. 当我在返回另一个接口的COM接口上调用方法时,punkVal每次都不同。

Yet if I use the old punkVal's to invoke that interfaces methods, it too works. 但是,如果我使用旧的punkVal来调用该接口方法,它也可以工作。 It seems like a lot of unnecessary objects(or probably pointers to objects) are being created but I need someway to determine if the returned interface is unique. 似乎正在创建许多不必要的对象(或可能是指向对象的指针),但我需要某种方式来确定返回的接口是否唯一。 All I know is that I invoke is returning an interface(punkVal) and the value is different every instance. 我所知道的是,我调用的是返回一个interface(punkVal),并且每个实例的值都不同。 The value pointed by that value is always the same, but I think it is because it points to the vtable or something, doesn't seem to be a reliable check. 该值所指向的值始终是相同的,但是我认为这是因为它指向vtable之类的东西,似乎不是可靠的检查。 That, or even seemingly disparate interfaces are all actually the same interface. 实际上,甚至看似完全不同的接口实际上都是相同的接口。

To be clear: 要清楚:

someCOMInterface foo();

I call invoke on foo and expect punkVal to be someCOMInterface, which I must later on query to call it's methods using invoke. 我在foo上调用invoke,并期望punkVal是someCOMInterface,稍后我必须在查询时使用调用调用它的方法。 But each time I call the first invoke I get a different someCOMInterface(the "same" but "different" in that the value returned by invoke). 但是每次我调用第一个调用时,我都会得到一个不同的someCOMInterface(“相同”但“不同”之处在于调用返回的值)。

This isn't uncommon. 这并不少见。 It is entirely up to the developer of the COM library whether interface pointers returned from multiple calls to the same method will return the same pointer or not. 从多次调用同一方法返回的接口指针是否返回相同的指针,完全取决于COM库的开发人员。

One of the reasons that different pointers may be returned is that the core object model used within a specific COM library may not be COM. 可能返回不同的指针的原因之一是,特定COM库中使用的核心对象模型可能不是COM。 I have, for example, written object models in C++ using things like shared_ptr , which arguably yields a better object model for C++ clients. 例如,我使用诸如shared_ptr东西在C ++中编写了对象模型,可以说它为C ++客户端提供了更好的对象模型。 But when I expose my C++ object model for interoperability (or, more generally, expose it as a DLL), COM is often a better choice. 但是,当我公开自己的C ++对象模型以实现互操作性(或更一般地说,将其公开为DLL)时,COM通常是一个更好的选择。 Since keeping an complex, hierarchical object model in sync with a set of wrapper classes can be difficult, wrapper objects may just be temporary -- created as necessary and destroyed whenever clients no longer use them. 由于使一个复杂的,分层的对象模型与一组包装器类保持同步可能很困难,因此包装器对象可能只是临时的-根据需要创建,并在客户端不再使用它们时销毁。

In these circumstances, the client may still need to know that the objects are "equal" -- two different objects that wrap the same inner object can be considered "equal." 在这些情况下,客户端可能仍然需要知道对象是“相等的”-包裹同一内部对象的两个不同的对象可以视为“相等的”。 To determine that, Microsoft defines the IObjectEquality interface. 为此,Microsoft定义了IObjectEquality接口。 This interface may be implemented by COM wrapper classes so that a client can explicitly check if two non-equal pointers are conceptually "equal" objects. 该接口可以由COM包装器类实现,以便客户端可以显式检查两个非相等指针在概念上是否为“相等”对象。 The objects you're using may or may not implement this interface. 您正在使用的对象可能会或可能不会实现此接口。 This blog post shows a complete example of determining object equality using this interface. 这篇博客文章显示了使用此接口确定对象相等性的完整示例。

If IObjectEquality is not implemented, it is up to the developer of the COM object to provide some means of making such a determination, usually by providing some sort of Name or ID or other identifying property. 如果未实现IObjectEquality ,则通常由COM对象的开发人员提供某种确定方法,通常是通过提供某种NameID或其他标识属性来进行。 For example, Excel's Application.Range property will return different pointers from subsequent calls with the same arguments. 例如,Excel的Application.Range属性将从具有相同参数的后续调用中返回不同的指针。 To determine if two ranges are equal, you can use the Range.Address method to get an "identifier" of that range, and then compare those identifiers. 若要确定两个范围是否相等,可以使用Range.Address方法获取该范围的“标识符”,然后比较这些标识符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM