Factoryvorlagenarray

Die Factoryvorlage enthält die folgenden öffentlichen Membervariablen:

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)

Die beiden Funktionszeiger m _ lpfnNew und m _ lpfnInitverwenden die folgenden Typdefinitionen:

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

Der erste ist die Instanziierungsfunktion für die Komponente. Die zweite ist eine optionale Initialisierungsfunktion. Wenn Sie eine Initialisierungsfunktion bereitstellen, wird sie aus der DLL-Einstiegspunktfunktion aufgerufen. (Die DLL-Einstiegspunktfunktion wird weiter unten in diesem Artikel erläutert.)

Angenommen, Sie erstellen eine DLL, die eine Komponente namens CMyComponent enthält, die von CUnknownerbt. Sie müssen die folgenden Elemente in ihrer DLL angeben:

  • Die Initialisierungsfunktion, eine öffentliche Methode, die eine neue Instanz von CMyComponent zurückgibt.
  • Ein globales Array von Factoryvorlagen mit dem Namen g _ Templates. Dieses Array enthält die Factoryvorlage für CMyComponent.
  • Eine globale Variable mit dem Namen g _ cTemplates, die die Größe des Arrays angibt.

Das folgende Beispiel zeigt, wie diese Elemente deklariert werden:

// 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]);    

Die CreateInstance -Methode ruft den Klassenkonstruktor auf und gibt einen Zeiger auf die neue Klasseninstanz zurück. Der Parameter pUnk ist ein Zeiger auf die Aggregierung von IUnknown. Sie können diesen Parameter einfach an den Klassenkonstruktor übergeben. Der Parameter pHr ist ein Zeiger auf einen HRESULT-Wert. Der Klassenkonstruktor legt diesen auf einen geeigneten Wert fest. Wenn der Konstruktor jedoch fehlschlägt, legen Sie den Wert auf E _ OUTOFMEMORY fest.

Das NAME-Makro generiert eine Zeichenfolge in Debugbuilds, wird aber in Verkaufsbuilds in NULL aufgelöst. Sie wird in diesem Beispiel verwendet, um der Komponente einen Namen zu geben, der in Debugprotokollen angezeigt wird, aber in der endgültigen Version keinen Arbeitsspeicher belegt.

Die CreateInstance -Methode kann einen beliebigen Namen haben, da die Klassenfactory auf den Funktionszeiger in der Factoryvorlage verweist. g _ Templates und g _ cTemplates sind jedoch globale Variablen, die von der Klassenfactory erwartet werden, sodass sie genau diese Namen aufweisen müssen.

Erstellen einer DirectShow-Filter-DLL