为什么QueryInterface查看两个不同的com项目的同一代码行
Why is QueryInterface looking at two different COM projects for the same line of code?
让我开始说我对com的运作非常没有经验,但是我的任务是为别人调试一个问题
我有两个名为PVTASKCOM和PVFORMSCOM的com项目,每个项目都有许多接口,但是我关注的两个项目是:
在pvtaskcom中的itaskActptr
iChartingObjectptr,在pvformscom中
引起我问题的代码行是:
ITaskActPtr pTaskAct = m_pChartObj;
其中m_pchartobj是iChartingObjectptr。我遇到的问题是,在一个工作流程中,Ptaskact在此作业之后是无效的,但在大多数其他工作流程中都很好。我使用调试器潜入这里,发现它正在查看查询方面的错误com条目。在正常工作的工作流程中,查询因面从pvtaskcom/pvtaskact.h获取条目:
BEGIN_COM_MAP(CTaskAct)
COM_INTERFACE_ENTRY(ITaskAct)
.
.
.
END_COM_MAP()
包含我要铸造的界面,然后查询以返回s_ok。
但是,在其他工作流中,m_pchartobj的实例化是相同的,但是出于某些奇怪的原因查看pvformscom/chartingingobject.h
出于某些奇怪的原因。BEGIN_COM_MAP(CChartingObject)
COM_INTERFACE_ENTRY(IChartingObject)
.
.
.
END_COM_MAP()
不包含我们试图施放的itaskact,因此查询返回e_nointerface。
我有什么问题是什么可能导致它在相同的代码中查看两个不同的com?这是某种继承问题吗?我只需要朝正确的方向迈出一步。
在工作流正常工作的工作流中,
QueryInterface
从pvtaskcom/pvtaskact.h抓取条目。H
不应该是。
这一行:
ITaskActPtr pTaskAct = m_pChartObj;
在引擎盖下这样做:
ITaskAct *pTaskAct = NULL;
m_pChartObj->QueryInterface(IID_ITaskAct, (void*)&pTaskAct);
如果它支持ITaskAct
接口,则询问IChartingObject
的实现对象,如果是这样,则要求将指针返回到该实现的指针。因此,此代码应仅查看COM_MAP
类的CC_4条目。它根本不应该看CTaskAct
类。
但是,在其他工作流中,
外观m_pChartObj
是相同的,但是QueryInterface
出于某些奇怪的原因,pvformscom/chartingObject.h
这是正确的行为,因为那是实际实现CChartingObject
的地方。如果CChartingObject
的COM_MAP
中没有ITaskAct
的条目,则正确的行为是CChartingObject::QueryInterface()
在E_NOINTERFACE
错误中失败。
因此,真正的问题是您的"工作"工作流程实际上是有缺陷的,而您的"非工作"工作流正在做正确的事情。
是什么可能导致它在同一行代码中查看两个不同的com?这是某种继承问题吗?
否。"工作"工作流程被损坏,简单明了。在IChartingObject
接口上调用QueryInterface()
应调用CChartingObject::QueryInterface()
,但显然是在调用CTaskAct::QueryInterface()
。所以要么
IChartingObject*
指针实际上指向CTaskAct
对象,而不是CChartingObject
对象某些东西损坏了内存,
IChartingObject
的VTable是毫无戒心的受害者。
我会怀疑前者。因此,在"工作"工作流程中,请确保IChartingObject*
指针实际上指向正确的对象。听起来好像有人服用了ITaskAct*
并将其类型化为IChartingObject*
,而无需使用QueryInterface()
。或者他们在某些对象上打电话给QueryInterface()
,并要求它用于IID_ITaskAct
,而不是IID_IChartingObject
,但随后将返回的指针保存在IChartingObject*
指针中,而不是ITaskAct*
指针中。
您可能会在管道中丢失一点。这是C 代码,旨在使COM变得更加严厉。COM的一个重要方面是客户端代码仅与接口一起使用。它对对象一无所知。接口是一个简单的合同,您可以调用的功能列表。iChartingObject将具有paint((函数。iTaskact不会有一个"任务"," Tasky",Schedule((函数。
注意m_pchartobj是一个非常误导的名称。它存储一个接口指针,而不是对象。但是并不少见,如果对象仅实现一个接口或具有您一直使用的"主导"接口,则很容易将接口指针视为对象指针。在服务器代码内隐藏对象是一个非常强大的目标,您只能进行接口调用。
所以itaskActptr ptaskact = m_pchartobj;基本上宣布:"我有一个图表,我想下一个任务函数调用"。喜欢schepen((。这要求com询问图表对象实现"您对任务接口合同有什么了解吗?"。不可避免地,它必须回到服务器,在cChartingObject的接口图中,以查看它是否也实现了itaskact。
因此,您看到的事情完全正常。答案是"否"。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法在 CLion 中构建 C++ 项目
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 欧拉项目#8答案是大以获得有效答案
- 从链接列表c++中删除一个项目
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 既然存在危险,为什么项目要使用-I include开关
- cmake在我的项目中所需的所有静态库都不成功
- 为什么QueryInterface查看两个不同的com项目的同一代码行
- 无法访问 ATL/COM C++ Outlook 加载项中的邮件项目
- VS COM项目以32位编译,但在尝试编译64位时引发错误C2259
- 正在创建com库,从空项目开始
- C# com 混淆在 C++ 项目中不起作用
- 在ATL项目中将NULL指针传递给进程外COM方法的正确方法
- 如何在Linux中使用COM ATL项目
- 在Qt项目中使用COM dll
- 如何在Visual Studio c++ ATL项目创建的COM .dll中添加新函数