Mendukung Beberapa Panggilan Balik
Jika Anda memanggil lebih dari satu metode asinkron, masing-masing memerlukan implementasi terpisah dari IMFAsyncCallback::Invoke. Namun, Anda mungkin ingin menerapkan panggilan balik di dalam satu kelas C++. Kelas hanya dapat memiliki satu metode Panggil , jadi salah satu solusinya adalah menyediakan kelas pembantu yang mendelegasikan Panggil panggilan ke metode lain pada kelas kontainer.
Kode berikut menunjukkan templat kelas bernama AsyncCallback
, yang menunjukkan pendekatan ini.
//////////////////////////////////////////////////////////////////////////
// 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;
};
Parameter templat adalah nama kelas kontainer. AsyncCallback
Konstruktor memiliki dua parameter: penunjuk ke kelas kontainer, dan alamat metode panggilan balik pada kelas kontainer. Kelas kontainer dapat memiliki beberapa instans AsyncCallback
kelas sebagai variabel anggota, satu untuk setiap metode asinkron. Ketika kelas kontainer memanggil metode asinkron, kelas kontainer menggunakan antarmuka IMFAsyncCallback dari objek yang sesuai AsyncCallback
. AsyncCallback
Ketika metode Panggil objek dipanggil, panggilan didelegasikan ke metode yang benar pada kelas kontainer.
Objek juga AsyncCallback
mendelegasikan panggilan AddRef dan Release ke kelas kontainer, sehingga kelas kontainer mengelola masa AsyncCallback
pakai objek. Ini menjamin bahwa AsyncCallback
objek tidak akan dihapus sampai objek kontainer itu sendiri dihapus.
Kode berikut menunjukkan cara menggunakan templat ini:
#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 )
Dalam contoh ini, kelas kontainer diberi nama CMyObject
. Variabel anggota m_CB adalah AsyncCallback
objek . CMyObject
Dalam konstruktor, variabel anggota m_CB diinisialisasi dengan alamat CMyObject::OnInvoke
metode .
Topik terkait
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk