【问题标题】:Invoking methods on ActiveX interface without a Wrapper class在没有 Wrapper 类的情况下调用 ActiveX 接口上的方法
【发布时间】:2018-05-08 14:33:59
【问题描述】:

我正在使用没有源代码的 3d 方 ActiveX 组件。我可以将组件添加到我的 MFC 对话框中。当我这样做时,会创建一个包含许多函数的包装类,如下所示:

void SetNextMovePCI2FastLink(short nNodeNumber, short nCardNumber)
    {
        static BYTE parms[] = VTS_I2 VTS_I2 ;
        InvokeHelper(0x109, DISPATCH_METHOD, VT_EMPTY, NULL, parms, nNodeNumber, nCardNumber);
    }

使用这些包装函数我可以正常运行。但是,由于从不同的线程访问 COM 对象,我需要为这个对象编组 COM 接口。如何在没有包装器的情况下直接调用 COM 接口上的方法?是否有一种简单的方法可以将包装器应用于原始 COM 接口,以便包装器可以重新使用?还是我必须使用IDispatch 接口的Invoke() 方法?如果是这样,有没有办法找出要调用的真正方法名称字符串是什么?包装器使用上面的 0x109 等数字来寻址每个方法。我能否以某种方式利用包装器的 InvokeHelper() 直接在给定的 COM 接口上调用方法?

【问题讨论】:

  • 正确的 COM 接口指针封送处理与直接调用 IDispatch::Invoke 无关。适用相同的标准规则。您只需按照通常的方式编组接口指针。
  • 谢谢罗曼。你看,编组不会导致问题。问题是无法在该接口上调用任何方法,无论是在编组之前还是之后。我知道在这个 ActiveX 上调用方法的唯一方法是通过包装类。包装类扩展 CWnd 对象。 Wrapper 使用的InvokeHelper() 机制属于CWnd. 但是如果我有一个指向原始接口的指针,wrapper 对我有什么好处?如何调用这个接口上的方法?
  • 此代码由 MFC 向导从类型库中自动生成。还有另一种方法,纯粹在代码中而不使用向导。你会使用#import directive。不使用 Dispatch::Invoke()。在你变得火热之前,一定要确保这个组件提供了你需要的代理/存根。
  • 我现在明白了。由于InvokeHelperIDispatch::Invoke 的一个比较薄的包装器,所以在将IDispatch 指针编组到另一个线程后,您可以直接调用新获得的IDispatch::Invoke 方法。显然您对使用包装很感兴趣,因为 in 简化了调用语法,解决方法之一是将指针放入 CComPtr<IDispatch> 并使用其 CComPtr<IDispatch>::Invoke0Invoke1InvokeNPutProperty 助手,它们是在功能上非常接近原始InvokeHelper
  • 罗马。 Invoke0..1..2.. 是IDispatch::Invoke() 的不同原型,我想? CComPtr,只有助于引用计数,而不是实际的函数调用?我会尝试.. 想避免因为IDispatch::Invoke() 看起来不友好。

标签: c++ visual-c++ mfc com activex


【解决方案1】:

我引用了 Igor Tandetnik 的回应:

“我使用MFC已经有一段时间了,所以我的记忆模糊。我相信包装器是从COleDispatchDriver派生的,它有一个来自IDispatch的构造函数以及AttachDispatch方法。使用这些,您也许可以获取原始的IDispatch 指针,将其编组到另一个线程,然后创建一个新的包装器实例并将指针附加到它。”

基本上,如果您想在编组到另一个线程后将 MFC 包装器用于 COM/ActiveX 对象,您可以使用 COleDispatchDriver 包装您的 IDispatch 并使用一些宏魔术来调整代码以调用相同的 InvokeHelper(..)调用驱动程序对象。或者,扩展包装器以使用包括通过驱动程序对封送接口进行操作,如下面的代码。谢谢,伊戈尔。

void SetCommsWrite(short nAddress, float fValue)
{
    static BYTE parms[] = VTS_I2 VTS_R4 ;
    InvokeHelper(0x136, DISPATCH_METHOD, VT_EMPTY, NULL, parms, nAddress, fValue);
}
void SetCommsWrite(short nAddress, float fValue, COleDispatchDriver & driver)
{
    static BYTE parms[] = VTS_I2 VTS_R4;
    driver.InvokeHelper(0x136, DISPATCH_METHOD, VT_EMPTY, NULL, parms, nAddress, fValue);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    相关资源
    最近更新 更多