Шаг 177.
Среда программирования Visual C++.
Анализ кода ATL COM-компонента. Определение класса компонента

    На этом шаге мы рассмотрим особенности определения класса компонента.

    Начиная с этого шага мы изучим исходный текст, сгенерированный мастерами ATL для Вашего СОМ-объекта, который включает объявление класса, тело класса, функции глобальной точки входа, сценарий регистрации в реестре и IDL-файл. После знакомства с ATL мы рассмотрим альтернативные способы разработки СОМ-объектов.

    Определение класса Вашего компонента находится в файле Encoder.h. Это стандартное определение класса C++, использующее множественное наследование.

class ATL_NO_VTABLE CEncoder : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CEncoder, &CLSID_Encoder>,
	public IEncoder
{
public:
	CEncoder()
	{
		m_Key = 1;
	}

DECLARE_REGISTRY_RESOURCEID(IDR_ENCODER)
DECLARE_NOT_AGGREGATABLE(CEncoder)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CEncoder)
	COM_INTERFACE_ENTRY(IEncoder)
END_COM_MAP()

// IEncoder
public:
	STDMETHOD(get_Key)(/*[out, retval]*/ short *pVal);
	STDMETHOD(put_Key)(/*[in]*/ short newVal);
	STDMETHOD(EncodeString)(/*[in]*/ const BSTR instring, 
                /*[out, retval]*/ BSTR * outstring);
protected:
	short m_Key;
};

    Класс наследует от трех базовых классов: CComObjectRootEx, CComCoClass и IEncoder. Первые два - шаблонные базовые классы ATL, а последний - интерфейс, объявленный в файле EncodeServer.h как абстрактный базовый класс. Определяемые методы интерфейса помещаются в класс IEncoder в качестве виртуальных функций. Предоставляемые нами версии этих функций в производных классах реализуют конкретные услуги СОМ-сервера. В открытом разделе в конце определения класса находится тело EncodeString().

    Класс CComObjectRootEx содержит реализацию по умолчанию методов QueryInterface(), AddRef() и Release() интерфейса IUnknown. Создавая производный класс, мы позволяем клиенту обращаться к QueryInterface() для получения указателя на любой из интерфейсов, поддерживаемых Вашим СОМ-объектом. Методы AddRef() и Release() ведут учет обращений к СОМ-объекту, чтобы держать его в памяти, только пока он нужен клиентам.

    Класс, производный от CComCoClass, получает реализацию по умолчанию фабрики классов, которая создает экземпляр СОМ-сервера. В качестве аргументов мы передаем в этот шаблонный базовый класс имя класса сервера (CEncoder) и ссылку на его GUID (CLSIDEncoder). Для генерации всех идентификаторов GUID ATL-мастера используют утилиту UUIDGEN.EXE.

    Другой важный элемент объявления класса - СОМ-карта. Она содержит список интерфейсов, поддерживаемых СОM-объектом. Добавление записей в СОМ-карту происходит с помощью макроса COM_INTERFACE_ENTRY. Внутренние механизмы каркаса поддерживают соответствующий массив структур ATL_INTMAP_ENTRY, которые связывают GUID интерфейсов и функции, возвращающие указатели на интерфейс. СОМ-карта используется методом по умолчанию QueryInterface(), унаследованным от шаблонного базового класса CComObjectRootEx. Всякий раз, когда клиентское приложение вызывает QueryInterface(), реализация по умолчанию просматривает эту карту в поисках соответствующего GUID интерфейса. Найдя подходящую ссылку, функция возвращает указатель на интерфейс.

    На следующем шаге мы рассмотрим реализацию методов компонента.




Предыдущий шаг Содержание Следующий шаг