Создание класса СОМ-объекта
Класс, поддерживающий интерфейс, готов.
Теперь следует сделать доступным для пользователей СОМ-объекта весь DLL-сервер, где живет ко-класс CoSay. Минимальным набором функций, которые должна экспортировать COM DLL, является реализация только одной функции DllGetClassObject. Обычно ее сопровождают еще три функции, но в данный момент мы рассматриваем лишь минимальный набор. DLL должна создать СОМ-объект и позволить работать с ним, получив, то есть записав по адресу ppv, адрес зарегистрированного интерфейса. Вы, конечно, заметили, что в предложении дважды использовано слово адрес.
Именно поэтому параметр ppv имеет тип void**. Введите эту функцию в конец файла МуСоm.срр:
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) { //=== Если идентификатор класса задан неправильно, if (rclsid!= CLSID_CoSay) // возвращаем код ошибки с указанием причины неудачи return CLASS_E_CLASSNOTAVAILABLE; //====== Создаем объект ко-класса CoSay *pSay = new CoSay; //=== Пытаемся получить адрес запрошенного интерфейса HRESULT hr = pSay › Query!nterface (riid, ppv); if (FAILED(hr)) delete pSay; return hr; }
Макроподстановка STDAPI при разворачивании превратится в:
extern "С" HRESULT stdcall.
Примечание
Работа по опознаванию объектов идет с идентификаторами класса (rclsid) и интерфейса (riid). Это является, как считают апологеты СОМ, одной из самых важных черт, которые вносят небывалый уровень надежности в функционирование СОМ-приложений. Весьма спорное утверждение, так как центром всей вселенной как разработчика, так и пользователя становится Windows-реестр, который открыт всем ветрам – как случайным, так и преднамеренным воздействиям со стороны человека и программы. Однако следует согласиться с тем, что уникальная идентификация снимает проблему случайного, но весьма вероятного совпадения имен интерфейсов, разработанных в разных частях света. То же относится и к именам классов, библиотек типов и т. д.