MFC COM服务器FindConnectionPoint报DISP_E_BADINDEX,求解itinfo参数
问题解答
一、itinfo参数是什么?
itinfo是IDispatch::GetTypeInfo方法的第一个参数,按照COM规范,它用于指定要获取的类型信息的索引。一个实现IDispatch的COM对象可以提供多个类型信息实例(比如对应不同接口、不同语言区域的类型定义),索引从0开始计数。如果对象仅支持一套类型信息,那么只有itinfo=0是有效的,传入其他值都会返回DISP_E_BADINDEX错误。
二、为什么itinfo不为0?
你的问题根源在于MFC连接点实现与手动添加的接口映射冲突:
- 你手动添加了
INTERFACE_PART(CAutomateDlgAutoProxy, IID_IConnectionPointContainer, Automate),但CCmdTarget只要定义了CONNECTION_MAP,就会自动实现IConnectionPointContainer接口。这一手动添加的接口部分会覆盖MFC的默认实现,导致内部调用逻辑混乱,最终在获取事件接口类型信息时传入了非0的itinfo值。 - 另外,
COleDispatchImpl默认只关联主自动化接口(IAutomate)的类型信息,它的GetTypeInfo方法只接受itinfo=0;而客户端调用FindConnectionPoint查找事件接口时,MFC的连接点实现需要获取IAutomateEvents的类型信息,此时错误的映射导致传入了非法的索引值。
三、解决步骤
1. 移除冲突的接口映射代码
删除你手动添加的INTERFACE_PART(CAutomateDlgAutoProxy, IID_IConnectionPointContainer, Automate),让MFC通过CONNECTION_MAP自动实现IConnectionPointContainer接口,避免逻辑冲突。
2. 确认事件接口的类型库配置
- 确保你的类型库(
.tlb文件)中包含IAutomateEvents的完整定义,且COM服务器注册时,类型库已正确注册到系统中。 - 检查
CAutomateDlgAutoProxy的类定义,确保DECLARE_DISPATCH_MAP、DECLARE_INTERFACE_MAP与连接点映射的关联逻辑正确,类型库能被正常加载。
3. 验证连接点映射的正确性
确认CONNECTION_PART中的IID_IAutomateEvents是事件接口的正确IID,无拼写或定义错误。
4. (可选)重写GetTypeInfo支持多类型信息
如果你的COM对象需要同时提供主接口和事件接口的类型信息,可以在CAutomateDlgAutoProxy中重写GetTypeInfo方法,根据索引返回对应类型信息:
STDMETHODIMP CAutomateDlgAutoProxy::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { if (pptinfo == nullptr) return E_POINTER; *pptinfo = nullptr; // 返回主自动化接口类型信息(索引0) if (itinfo == 0) { IID iid; if (GetDispatchIID(&iid)) { return GetTypeInfoOfGuid(lcid, iid, pptinfo); } return DISP_E_BADINDEX; } // 返回事件接口类型信息(索引1) else if (itinfo == 1) { return GetTypeInfoOfGuid(lcid, IID_IAutomateEvents, pptinfo); } else { return DISP_E_BADINDEX; } }
内容的提问来源于stack exchange,提问作者JKC
相关产品推荐
相关产品推荐

