在COM中绝对需要调用QueryInterface()吗?

时间:2019-06-03 22:49:55

标签: c++ winapi com shell-extensions queryinterface

this C ++ / COM Shell扩展教程中,程序员演示了(出于教育目的)您可以放弃调用QueryInterface(),而只是传递一个通用对象。至少在实现DllGetClassObject()时有效。他说QueryInterface()的目的仅仅是让每个对象自己说明是否支持给定的接口。

与此同时,Microsoft似乎say QueryInterface()是获得指向对象上特定接口的指针所必需的。

那么QueryInterface()在什么程度上是必要的?有没有时间调用QueryInterface()是绝对必要的,没有它,代码将无法工作?还是像视频教程所建议的那样,使对象本身在技术上足够?

1 个答案:

答案 0 :(得分: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)

对象的实例可能指向IFoo的v表指针或IBar的v表指针。在不知道它到底是哪一个的情况下调用第4个方法将崩溃,因为参数数不相同。即使签名相同,调用任意方法也不是一个好主意。

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

在学习COM基础知识时,我建议尝试使用C而不是C ++进行编码,这会迫使您自己处理所有v表间接操作。看看this series了解详情。