Compartilhar via


Matriz de modelo de fábrica

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

O modelo de fábrica contém as seguintes variáveis de membro público:

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)

Os dois ponteiros de função, m_lpfnNew e m_lpfnInit, usam as seguintes definições de tipo:

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

A primeira é a função de instanciação do componente. A segunda é uma função de inicialização opcional. Se você fornecer uma função de inicialização, ela será chamada de dentro da função de ponto de entrada da DLL. (A função de ponto de entrada DLL é discutida posteriormente neste artigo.)

Suponha que você esteja criando uma DLL que contém um componente chamado CMyComponent, que herda de CUnknown. Você deve fornecer os seguintes itens em sua DLL:

  • A função de inicialização, um método público que retorna uma nova instância do CMyComponent.
  • Uma matriz global de modelos de fábrica, chamada g_Templates. Essa matriz contém o modelo de fábrica para CMyComponent.
  • Uma variável global chamada g_cTemplates que especifica o tamanho da matriz.

O exemplo a seguir mostra como declarar esses itens:

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

O CreateInstance método chama o construtor de classe e retorna um ponteiro para a nova instância de classe. O parâmetro pUnk é um ponteiro para a agregação de IUnknown. Você pode simplesmente passar esse parâmetro para o construtor de classe. O parâmetro pHr é um ponteiro para um valor HRESULT. O construtor de classe define isso como um valor apropriado, mas se o construtor falhar, defina o valor como E_OUTOFMEMORY.

A macro NAME gera uma cadeia de caracteres em builds de depuração, mas é resolvida como NULL em builds de varejo. Ele é usado neste exemplo para dar ao componente um nome que aparece nos logs de depuração, mas não ocupa a memória na versão final.

O CreateInstance método pode ter qualquer nome, pois a fábrica de classes se refere ao ponteiro de função no modelo de fábrica. No entanto, g_Templates e g_cTemplates são variáveis globais que a fábrica de classes espera encontrar, portanto, elas devem ter exatamente esses nomes.

Como criar uma DLL de filtro DirectShow