C++ 在没有包装类的ActiveX接口上调用方法

C++ 在没有包装类的ActiveX接口上调用方法,c++,visual-c++,mfc,com,activex,C++,Visual C++,Mfc,Com,Activex,我使用的是一个没有源代码的3d party ActiveX组件。我可以将组件添加到我的MFC对话框中。当我这样做时,将创建一个包装类,其中包含许多函数,如下所示: void SetNextMovePCI2FastLink(short nNodeNumber, short nCardNumber) { static BYTE parms[] = VTS_I2 VTS_I2 ; InvokeHelper(0x109, DISPATCH_METHOD, VT_E

我使用的是一个没有源代码的3d party 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接口上调用方法吗?

我引用了Igor Tandetnik的一个回应:

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

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

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);
}

正确的COM接口指针封送与直接调用
IDispatch::Invoke
无关。同样的标准规则也适用。您只需按照一贯的方式封送接口指针。感谢Roman。您知道,封送不会导致问题。问题是无法在该接口上调用任何方法,无论是在该接口变为m之前还是之后arshaled。据我所知,在这个ActiveX上调用方法的唯一方法是通过包装器类。包装器类扩展了
CWnd
对象。
InvokeHelper()
包装器使用的机制属于
CWnd。
但是如果我有一个指向原始接口的指针,包装器对我有什么好处?如何在此接口上调用方法?此代码是由MFC向导从类型库自动生成的。有另一种方法可以做到这一点,完全在代码中而不使用向导。您可以使用.W它不使用Dispatch::Invoke()。在您开始使用它之前,请确保此组件提供了所需的代理/存根。我现在明白了。由于
InvokeHelper
IDispatch::Invoke
上相对较薄的包装,在封送
IDispatch
指向另一个线程的指针后,您可以调用新获得的
IDispatch::Invoke
方法显然,您对使用包装感兴趣,因为in简化了调用语法,解决方法之一是将指针放在
CComPtr
中,并使用其
CComPtr::Invoke0
Invoke1
InvokeN
PutProperty
帮助程序,它们与原始
InvokeHel>非常接近根据functionality.Roman中的
。Invoke0..1..2..是
IDispatch::Invoke()
的不同原型,我想?
CComPtr
,只在引用计数方面有帮助,而不是实际的函数调用?我将尝试..想要避免,因为
IDispatch::Invoke()
看起来不友好。