首先,我要说我对COM的工作非常缺乏经验,但是我的任务是调试其他人的问题

我有两个名为pvTaskCOM和pvFormsCOM的COM项目,每个项目都有很多接口(interface),但是我关心的两个是:

pTaskTaskCOM中的ITaskActPtr

pvFormsCOM中的IChartingObjectPtr

导致我的问题的代码行是:

ITaskActPtr pTaskAct = m_pChartObj;

其中m_pChartObj是一个IChartingObjectPtr。我遇到的问题是,在一个工作流中进行此分配后,pTaskAct为NULL,但在其他大多数工作流中都可以使用。我使用调试器深入研究了这里发生的情况,发现它在QueryInterface期间查找了错误的COM条目。在工作正常的工作流程中,QueryInterface从pvTaskCOM / pvTaskAct.h中获取条目:
BEGIN_COM_MAP(CTaskAct)
  COM_INTERFACE_ENTRY(ITaskAct)
  .
  .
  .
END_COM_MAP()

其中包含我要投射到的接口(interface),QueryInterface返回S_OK。

但是在另一个工作流程中,m_pChartObj以相同的方式实例化,但是QueryInterface由于某种奇怪的原因在pvFormsCOM / ChartingObject.h中查找
BEGIN_COM_MAP(CChartingObject)
  COM_INTERFACE_ENTRY(IChartingObject)
  .
  .
  .
END_COM_MAP()

其中不包含我们要投射到的ITaskAct,因此QueryInterface返回E_NOINTERFACE。

我的问题是什么可能导致它在同一行代码中查看两个不同的COM?这是某种继承问题吗?我只需要朝正确的方向迈出一步。

最佳答案



不应该。

这行:

ITaskActPtr pTaskAct = m_pChartObj;

正在后台执行此操作:
ITaskAct *pTaskAct = NULL;
m_pChartObj->QueryInterface(IID_ITaskAct, (void*)&pTaskAct);

它询问IChartingObject的实现对象是否支持ITaskAct接口(interface),如果支持,则返回指向该实现的指针。因此,此代码应仅查看COM_MAP类的CChartingObject条目。它根本不应该查看CTaskAct类。



这是正确的行为,因为实际上是在实现CChartingObject的地方。如果ITaskActCOM_MAP中没有CChartingObject的条目,则正确的行为是CChartingObject::QueryInterface()失败并出现E_NOINTERFACE错误。

因此,真正的问题是您的“工作”工作流程实际上存在缺陷,而您的“不工作”工作流程却在做正确的事情。



不能。“工作”工作流程已损坏,简单明了。在QueryInterface()接口(interface)上调用IChartingObject应该是在调用CChartingObject::QueryInterface(),但显然是在调用CTaskAct::QueryInterface()。所以要么
  • IChartingObject*指针实际上指向的是CTaskAct对象而不是CChartingObject对象
  • 某些东西损坏了内存,并且IChartingObject的vtable是毫无戒心的受害者。

  • 我会怀疑前者。因此,在“工作”工作流程中,请确保IChartingObject*指针实际上指向正确的对象。听起来有人在不使用ITaskAct*的情况下拿了IChartingObject*并将其类型转换为QueryInterface()。或者,他们在某个对象上调用了QueryInterface()并要求它提供IID_ITaskAct而不是IID_IChartingObject,然后将返回的指针保存在IChartingObject*指针中,而不是ITaskAct*指针中。

    关于c++ - 为什么QueryInterface在同一行代码中查看两个不同的COM项目?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43688165/

    10-11 00:23