支持多个回调
如果调用多个异步方法,则每个方法都需要 单独的 IMFAsyncCallback::Invoke 实现。 但是,你可能希望在单个 C++ 类中实现回调。 类只能有一个 Invoke 方法,因此一种解决方案是提供一个帮助程序类,用于将 Invoke 调用委托给容器类上的另一个方法。
以下代码演示名为 AsyncCallback
的类模板,该模板演示了此方法。
//////////////////////////////////////////////////////////////////////////
// AsyncCallback [template]
//
// Description:
// Helper class that routes IMFAsyncCallback::Invoke calls to a class
// method on the parent class.
//
// Usage:
// Add this class as a member variable. In the parent class constructor,
// initialize the AsyncCallback class like this:
// m_cb(this, &CYourClass::OnInvoke)
// where
// m_cb = AsyncCallback object
// CYourClass = parent class
// OnInvoke = Method in the parent class to receive Invoke calls.
//
// The parent's OnInvoke method (you can name it anything you like) must
// have a signature that matches the InvokeFn typedef below.
//////////////////////////////////////////////////////////////////////////
// T: Type of the parent object
template<class T>
class AsyncCallback : public IMFAsyncCallback
{
public:
typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
{
}
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(AsyncCallback, IMFAsyncCallback),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef() {
// Delegate to parent class.
return m_pParent->AddRef();
}
STDMETHODIMP_(ULONG) Release() {
// Delegate to parent class.
return m_pParent->Release();
}
// IMFAsyncCallback methods
STDMETHODIMP GetParameters(DWORD*, DWORD*)
{
// Implementation of this method is optional.
return E_NOTIMPL;
}
STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
{
return (m_pParent->*m_pInvokeFn)(pAsyncResult);
}
T *m_pParent;
InvokeFn m_pInvokeFn;
};
模板参数是容器类的名称。 构造 AsyncCallback
函数有两个参数:指向容器类的指针和容器类上回调方法的地址。 容器类可以将类的 AsyncCallback
多个实例作为成员变量,每个异步方法对应一个实例。 当容器类调用异步方法时,它将使用相应AsyncCallback
对象的 IMFAsyncCallback 接口。
AsyncCallback
调用对象的 Invoke 方法时,调用将委托给容器类上的正确方法。
对象 AsyncCallback
还委托对容器类的 AddRef 和 Release 调用,因此容器类管理对象的生存期 AsyncCallback
。 这可以保证在 AsyncCallback
删除容器对象本身之前不会删除该对象。
以下代码演示如何使用此模板:
#pragma warning( push )
#pragma warning( disable : 4355 ) // 'this' used in base member initializer list
class CMyObject : public IUnknown
{
public:
CMyObject() : m_CB(this, &CMyObject::OnInvoke)
{
// Other initialization here.
}
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
private:
AsyncCallback<CMyObject> m_CB;
HRESULT OnInvoke(IMFAsyncResult *pAsyncResult);
};
#pragma warning( pop )
在此示例中,容器类名为 CMyObject
。
m_CB 成员变量是 对象AsyncCallback
。 在 CMyObject
构造函数中, m_CB 成员变量使用 方法的 CMyObject::OnInvoke
地址初始化。
相关主题