Udostępnij za pośrednictwem


Tablica szablonów fabryki

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]

Szablon fabryki zawiera następujące publiczne zmienne składowe:

const WCHAR *              m_Name;                // Name
const CLSID *              m_ClsID;               // CLSID
LPFNNewCOMObject           m_lpfnNew;             // Function to create an instance
                                                  //   of the component
LPFNInitRoutine            m_lpfnInit;            // Initialization function (optional)
const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; // Set-up information (for filters)

Dwa wskaźniki funkcji, m_lpfnNew i m_lpfnInit, używają następujących definicji typów:

typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);

Pierwszy to funkcja tworzenia wystąpienia składnika. Drugi to opcjonalna funkcja inicjowania. Jeśli podasz funkcję inicjowania, jest wywoływana z wewnątrz funkcji punktu wejścia biblioteki DLL. (Funkcja punktu wejścia biblioteki DLL została omówiona w dalszej części tego artykułu).

Załóżmy, że tworzysz bibliotekę DLL zawierającą składnik o nazwie CMyComponent, który dziedziczy z CUnknown. Należy podać następujące elementy w pliku DLL:

  • Funkcja inicjowania , metoda publiczna, która zwraca nowe wystąpienie klasy CMyComponent.
  • Globalna tablica szablonów fabryk o nazwie g_Templates. Ta tablica zawiera szablon fabryki CMyComponent.
  • Zmienna globalna o nazwie g_cTemplates określająca rozmiar tablicy.

W poniższym przykładzie pokazano, jak zadeklarować te elementy:

// Public method that returns a new instance. 
CUnknown * WINAPI CMyComponent::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
{
    CMyComponent *pNewObject = new CMyComponent(NAME("My Component"), pUnk, pHr );
    if (pNewObject == NULL) {
        *pHr = E_OUTOFMEMORY;
    }
    return pNewObject;
} 

CFactoryTemplate g_Templates[1] = 
{
    { 
      L"My Component",                // Name
      &CLSID_MyComponent,             // CLSID
      CMyComponent::CreateInstance,   // Method to create an instance of MyComponent
      NULL,                           // Initialization function
      NULL                            // Set-up information (for filters)
    }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);    

Metoda CreateInstance wywołuje konstruktor klasy i zwraca wskaźnik do nowego wystąpienia klasy. Parametr pUnk jest wskaźnikiem do agregacji IUnknown. Ten parametr można po prostu przekazać do konstruktora klasy. Parametr pHr jest wskaźnikiem do wartości HRESULT. Konstruktor klasy ustawia tę wartość na odpowiednią wartość, ale jeśli konstruktor ulegnie awarii, ustaw wartość na E_OUTOFMEMORY.

Makro NAME generuje ciąg w kompilacjach debugowania, ale rozpoznaje NULL w kompilacjach detalicznych. Jest on używany w tym przykładzie, aby nadać składnikowi nazwę wyświetlaną w dziennikach debugowania, ale nie zajmuje pamięci w wersji końcowej.

Metoda CreateInstance może mieć dowolną nazwę, ponieważ fabryka klas odwołuje się do wskaźnika funkcji w szablonie fabryki. Jednak g_Templates i g_cTemplates to zmienne globalne, których oczekuje fabryka klas, więc muszą mieć dokładnie te nazwy.

Jak utworzyć bibliotekę DLL filtru DirectShow