首先,我要说我对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
的地方。如果ITaskAct
的COM_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/