【发布时间】: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()。在你变得火热之前,一定要确保这个组件提供了你需要的代理/存根。
-
我现在明白了。由于
InvokeHelper是IDispatch::Invoke的一个比较薄的包装器,所以在将IDispatch指针编组到另一个线程后,您可以直接调用新获得的IDispatch::Invoke方法。显然您对使用包装很感兴趣,因为 in 简化了调用语法,解决方法之一是将指针放入CComPtr<IDispatch>并使用其CComPtr<IDispatch>::Invoke0、Invoke1、InvokeN、PutProperty助手,它们是在功能上非常接近原始InvokeHelper。 -
罗马。 Invoke0..1..2.. 是
IDispatch::Invoke()的不同原型,我想?CComPtr,只有助于引用计数,而不是实际的函数调用?我会尝试.. 想避免因为IDispatch::Invoke()看起来不友好。
标签: c++ visual-c++ mfc com activex