如果您呼叫多個異步方法,則每個方法都需要獨立實作 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 方法的位址初始化。
相關主題