【问题标题】:C++ DispInvoke fails to find memberC++ DispInvoke 找不到成员
【发布时间】:2011-11-03 18:42:55
【问题描述】:

场景是这样的:

  • 我有一个 COM 对象要问问题。将其命名为 ICom。
  • COM 对象要求我实现一个 IDispatch,它是 IComEvents 的后代,它会通知我发生事件。
  • 我实现了一个 IDispatch 并将其连接到 COM 接口。

到目前为止一切顺利。我的 IComEvents 后裔的 Invoke() 在事件发生时被调用。

现在的重点是我必须手动解析 Invoke() 参数。比如一个通知函数是HRESULT OnMouseHit(int x),我要从DispID中检测到这个函数,然后手动调用,比如

if (dispIdMember == 0xfa)
 {
 OnMouseHit(pDispParams->rgvarg[0].pIntVal); 
 }

对于我想要实现的所有功能,我都必须这样做。但是我看到了 DispInvoke() 函数,它可能会自动为我执行此操作,并使用正确的参数为 dispId 调用适当的重载方法:

DispInvoke(this,m_ptinfo,dispIdMember,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);

如何生成 m_ptinfo?通过使用 COM 对象的 libid 调用 LoadRegTypeLib,然后使用 IComEvents 的 IID 调用 ITypeLib::GetTypeInfoOfGuid()。但是,DispInvoke() 总是返回“找不到成员”。

会有什么问题?我希望 DispInvoke 解析类型信息,从 DispID 中找到成员函数名称,然后使用“this”指针从 vtbl 中获取函数地址。

我做错了什么?

非常感谢。 迈克尔。

【问题讨论】:

    标签: c++ automation idispatch


    【解决方案1】:

    IComEvents 是双接口还是分接口?如果它是纯调度接口,则它没有 vtable。 DispInvoke 要求接口有vtable(即是双接口)。

    【讨论】:

    • 我明白了。它必须是没有 vtable 的接口。但是那么 DispInvoke 有什么用呢? Windows 中几乎所有的通知界面都是以相同的方式构建的。
    • @Michael 我认为 DispInvoke 旨在帮助实现普通的双接口(实现者通常也是接口的创建者)而不是事件(回调,通知)接口,实现者是特别不是界面的创建者。请注意,通常将接口设为双而不是分派接口不会造成任何损失,但对于事件接口而言,将其设为双意味着脚本语言(无法创建 vtable)将无法接收事件。
    猜你喜欢
    • 2014-08-28
    • 2023-04-08
    • 2012-09-23
    • 2019-09-03
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多