Массив шаблонов фабрики
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи аудио и видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
Шаблон фабрики содержит следующие открытые переменные-члены:
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)
Два указателя функции, m_lpfnNew и m_lpfnInit, используют следующие определения типов:
typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
Первое — это функция создания экземпляра компонента. Второй — это необязательная функция инициализации. Если вы предоставляете функцию инициализации, она вызывается из-за функции точки входа DLL. (Функция точки входа DLL рассматривается далее в этой статье.)
Предположим, вы создаете библиотеку DLL, содержащую компонент CMyComponent, который наследует от CUnknown. В библиотеке DLL необходимо указать следующие элементы:
- Функция инициализации— открытый метод, возвращающий новый экземпляр CMyComponent.
- Глобальный массив шаблонов фабрики с именем g_Templates. этот массив содержит шаблон фабрики для CMyComponent.
- Глобальная переменная с именем g_cTemplates, указывающая размер массива.
В следующем примере показано, как объявить эти элементы:
// 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]);
Метод CreateInstance
вызывает конструктор классов и возвращает указатель на новый экземпляр класса. Параметр pUnk — это указатель на агрегирование IUnknown. Этот параметр можно просто передать конструктору классов. Параметр pHr — это указатель на значение HRESULT. Конструктор класса задает для этого соответствующее значение, но если конструктор завершается ошибкой, задайте значение E_OUTOFMEMORY.
Макрос NAME создает строку в отладочных сборках, но разрешает null в розничных сборках. Он используется в этом примере, чтобы дать компоненту имя, которое отображается в журналах отладки, но не занимает память в окончательной версии.
Метод CreateInstance
может иметь любое имя, так как фабрика классов ссылается на указатель функции в шаблоне фабрики. Однако g_Templates и g_cTemplates являются глобальными переменными, которые фабрика классов ожидает найти, поэтому они должны иметь именно эти имена.
Связанные разделы