1

这个C++/COM shell 扩展教程中,程序员演示了(出于启发目的)您可以放弃调用QueryInterface()并简单地传递一个通用对象。至少在实施时有效DllGetClassObject()。他说,目的QueryInterface()只是让每个对象自己说明它是否支持给定的接口。

与此同时,微软似乎QueryInterface()要获得指向对象上特定接口的指针是必要的。

那么需要到什么程度QueryInterface()呢?是否有任何时候调用QueryInterface()是绝对必要的,没有它,代码就无法工作?还是如视频教程所暗示的那样,从技术上获取对象本身就足够了?

4

1 回答 1

5

QueryInterface不,作为一般规则,除非您知道您拥有的接口指针已经正确,否则您不能跳过调用。

如果我们想象一个实现 IFoo 和 IBar 的对象,布局可能看起来像这样:

VT
  IFoo_QueryInterface(...)
  IFoo_AddRef()
  IFoo_Release()
  IFoo_FooFight(int, int)
VT
  IBar_QueryInterface(...)
  IBar_AddRef()
  IBar_Release()
  IBar_BarBarBar(int)

对象的一个​​实例可能指向IFoos v-table 指针或IBars v-table 指针。在不知道它到底是哪一个的情况下调用第四个方法会崩溃,因为参数计数不一样。即使签名相同,调用任意方法也不是一个好主意。

您所指的视频只是因为呼叫者DllGetClassObject通常只要求IClassFactory. 但即使在那里也不安全,因为有人可能会要求IClassFactory2代替。因此,正确的DllGetClassObject实现也应该调用QueryInterface.

我建议在学习 COM 基础知识时尝试用 C 而不是 C++ 编写代码,这会迫使您自己处理所有 v-table 间接寻址。看看这个系列的详细信息。

于 2019-06-04T02:23:31.843 回答