Bagikan melalui


Menggunakan CUnknown

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Pengambilan Audio /Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Pengambilan Audio/Video di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

DirectShow mengimplementasikanIUnknown di kelas dasar yang disebut CUnknown. Anda dapat menggunakan CUnknown untuk memperoleh kelas lain, hanya mengambil alih metode yang berubah di seluruh komponen. Sebagian besar kelas dasar lainnya di DirectShow berasal dari CUnknown, sehingga komponen Anda dapat mewarisi langsung dari CUnknown atau dari kelas dasar lain.

INonDelegatingUnknown

CUnknown mengimplementasikan INonDelegatingUnknown. Ini mengelola jumlah referensi secara internal, dan dalam sebagian besar situasi kelas turunan Anda dapat mewarisi dua metode penghitungan referensi tanpa perubahan. Ketahuilah bahwa CUnknown menghapus dirinya sendiri ketika jumlah referensi turun ke nol. Di sisi lain, Anda harus menggantikan CUnknown::NonDelegatingQueryInterface, karena metode di kelas dasar mengembalikan E_NOINTERFACE jika menerima IID selain IID_IUnknown. Di kelas turunan Anda, uji IID antarmuka yang Anda dukung, seperti yang ditunjukkan dalam contoh berikut:

STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    if (riid == IID_ISomeInterface)
    {
        return GetInterface((ISomeInterface*)this, ppv);
    }
    // Default: Call parent class method. 
    // The CUnknown class must be in the inheritance chain.
    return CParentClass::NonDelegatingQueryInterface(riid, ppv);
}

Fungsi utilitas GetInterface (lihat COM Helper Functions) mengatur pointer, menaikkan jumlah referensi secara aman dalam utas, dan mengembalikan S_OK. Dalam kasus default, panggil metode kelas dasar dan kembalikan hasilnya. Saat Anda meneruskan dari kelas dasar lain, panggil metode NonDelegatingQueryInterface. Ini memungkinkan Anda mendukung semua antarmuka yang didukung kelas induk.

IUnknown

Seperti disebutkan sebelumnya, versi pendelegasian IUnknown sama untuk setiap komponen, karena hanya sebatas memanggil instance yang tepat dari versi yang tidak mendelegasikan. Untuk kenyamanan, file header Combase.h berisi makro, DECLARE_IUNKNOWN, yang mendeklarasikan tiga metode pendelegasian sebagai metode sebaris. Ini meluas ke kode berikut:

STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {      
    return GetOwner()->QueryInterface(riid,ppv);            
};                                                          
STDMETHODIMP_(ULONG) AddRef() {                             
    return GetOwner()->AddRef();                            
};                                                          
STDMETHODIMP_(ULONG) Release() {                            
    return GetOwner()->Release();                           
};

Fungsi utilitas CUnknown::GetOwner mengambil pointer ke antarmuka IUnknown dari komponen yang memiliki komponen ini. Untuk komponen agregat, pemiliknya adalah komponen luar. Jika tidak, komponen mengelola dirinya sendiri. Sertakan makro DECLARE_IUNKNOWN di bagian publik definisi kelas Anda.

Konstruktor Kelas

Konstruktor kelas Anda harus memanggil metode konstruktor untuk kelas induk, selain apa pun yang dilakukannya khusus untuk kelas Anda. Contoh berikut adalah metode konstruktor umum:

CMyComponent(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr) 
    : CUnknown(tszName, pUnk, phr)
{ 
    /* Other initializations */ 
};

Metode ini mengambil parameter berikut, yang diteruskannya langsung ke metode konstruktor CUnknown.

  • tszName menentukan nama untuk komponen.
  • pUnk adalah penunjuk ke IUnknown yang bersifat menggabungkan.
  • pHr adalah penunjuk ke nilai HRESULT, yang menunjukkan keberhasilan atau kegagalan metode.

Ringkasan

Contoh berikut menunjukkan kelas turunan yang mendukung IUnknown dan antarmuka hipotetis bernama ISomeInterface:

class CMyComponent : public CUnknown, public ISomeInterface
{
public:

    DECLARE_IUNKNOWN;

    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    {
        if( riid == IID_ISomeInterface )
        {
            return GetInterface((ISomeInterface*)this, ppv);
        }
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }

    CMyComponent(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr) 
        : CUnknown(tszName, pUnk, phr)
    { 
        /* Other initializations */ 
    };

    // More declarations will be added later.
};

Contoh ini mengilustrasikan poin-poin berikut:

  • Kelas CUnknown mengimplementasikan antarmukaIUnknown. Komponen baru mewarisi dari CUnknown dan dari antarmuka apa pun yang didukung oleh komponen tersebut. Komponen dapat berasal sebagai gantinya dari kelas dasar lain yang mewarisi dari CUnknown.
  • Makro DECLARE_IUNKNOWN mendeklarasikan metodeIUnknownyang didelegasikan sebagai metode sebaris.
  • Kelas CUnknown menyediakan implementasi untuk INonDelegatingUnknown.
  • Untuk mendukung antarmuka selain IUnknown, kelas turunan harus mengambil alih metodeNonDelegatingQueryInterface dan menguji IID antarmuka baru.
  • Konstruktor kelas memanggil fungsi konstruktor untuk CUnknown.

Langkah selanjutnya dalam menulis filter adalah mengaktifkan aplikasi untuk membuat instans baru komponen. Ini memerlukan pemahaman mengenai DLL dan hubungannya dengan pabrik kelas dan metode konstruktor kelas. Untuk informasi selengkapnya, lihat Cara Membuat DLL Filter DirectShow.

Cara Menerapkan IUnknown