为什么 COM 接口 return 相同调用方法的不同值?
Why does COM interface return different values for same invoking method?
当我在一个 COM 接口上调用一个 returns 另一个接口的方法时,每次 punkVal 都不一样。
然而,如果我使用旧的 punkVal 来调用该接口方法,它也能正常工作。似乎正在创建很多不必要的对象(或者可能是指向对象的指针),但我需要某种方式来确定返回的接口是否是唯一的。我所知道的是我调用的是返回一个接口(punkVal)并且每个实例的值都不同。该值指向的值始终相同,但我认为这是因为它指向 vtable 或其他东西,似乎不是可靠的检查。那,甚至看似完全不同的接口,其实都是同一个接口。
要明确:
someCOMInterface foo();
我在 foo 上调用 invoke 并期望 punkVal 是 someCOMInterface,稍后我必须查询它以使用 invoke 调用它的方法。但是每次我调用第一个调用时,我都会得到一个不同的 someCOMInterface("same" 但 "different" 因为调用返回的值)。
这并不少见。由多次调用同一方法得到的接口指针 return 是否 return 是同一个指针完全取决于 COM 库的开发人员。
可能 returned 不同指针的原因之一是特定 COM 库中使用的核心对象模型可能不是 COM。例如,我使用 shared_ptr
之类的东西在 C++ 中编写了对象模型,这可以说为 C++ 客户端生成了更好的对象模型。但是当我公开我的 C++ 对象模型以实现互操作性时(或者更一般地说,将其公开为 DLL),COM 通常是更好的选择。由于保持复杂的分层对象模型与一组包装器同步 类 可能很困难,因此包装器对象可能只是临时的——根据需要创建并在客户不再使用它们时销毁。
在这些情况下,客户端可能仍然需要知道对象是 "equal" -- 可以考虑包装同一内部对象的两个不同对象 "equal." 要确定这一点,Microsoft 定义IObjectEquality
interface. 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. The objects you're using may or may not implement this interface. This blog post 显示了使用此接口确定对象相等性的完整示例。
如果 IObjectEquality
没有实现,则由 COM 对象的开发人员提供一些方法来做出这样的决定,通常是提供某种 Name
或 ID
或其他标识 属性。例如,Excel 的 Application.Range
property will return different pointers from subsequent calls with the same arguments. To determine if two ranges are equal, you can use the Range.Address
方法获取该范围的 "identifier",然后比较这些标识符。
当我在一个 COM 接口上调用一个 returns 另一个接口的方法时,每次 punkVal 都不一样。
然而,如果我使用旧的 punkVal 来调用该接口方法,它也能正常工作。似乎正在创建很多不必要的对象(或者可能是指向对象的指针),但我需要某种方式来确定返回的接口是否是唯一的。我所知道的是我调用的是返回一个接口(punkVal)并且每个实例的值都不同。该值指向的值始终相同,但我认为这是因为它指向 vtable 或其他东西,似乎不是可靠的检查。那,甚至看似完全不同的接口,其实都是同一个接口。
要明确:
someCOMInterface foo();
我在 foo 上调用 invoke 并期望 punkVal 是 someCOMInterface,稍后我必须查询它以使用 invoke 调用它的方法。但是每次我调用第一个调用时,我都会得到一个不同的 someCOMInterface("same" 但 "different" 因为调用返回的值)。
这并不少见。由多次调用同一方法得到的接口指针 return 是否 return 是同一个指针完全取决于 COM 库的开发人员。
可能 returned 不同指针的原因之一是特定 COM 库中使用的核心对象模型可能不是 COM。例如,我使用 shared_ptr
之类的东西在 C++ 中编写了对象模型,这可以说为 C++ 客户端生成了更好的对象模型。但是当我公开我的 C++ 对象模型以实现互操作性时(或者更一般地说,将其公开为 DLL),COM 通常是更好的选择。由于保持复杂的分层对象模型与一组包装器同步 类 可能很困难,因此包装器对象可能只是临时的——根据需要创建并在客户不再使用它们时销毁。
在这些情况下,客户端可能仍然需要知道对象是 "equal" -- 可以考虑包装同一内部对象的两个不同对象 "equal." 要确定这一点,Microsoft 定义IObjectEquality
interface. 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. The objects you're using may or may not implement this interface. This blog post 显示了使用此接口确定对象相等性的完整示例。
如果 IObjectEquality
没有实现,则由 COM 对象的开发人员提供一些方法来做出这样的决定,通常是提供某种 Name
或 ID
或其他标识 属性。例如,Excel 的 Application.Range
property will return different pointers from subsequent calls with the same arguments. To determine if two ranges are equal, you can use the Range.Address
方法获取该范围的 "identifier",然后比较这些标识符。