на начало
На главную страницу
Форум   

Статья :: Создание класса СОМ-объекта

 

Создание класса СОМ-объекта

Подключите к проекту новый файл MyCom.h, в который надо поместить объявление класса CoSay. Как вы помните, он должен быть потомком экспортируемого интерфейса iSay и дать тела всем методам, унаследованным от всех своих абстрактных предков (isay, lUnknown). Введите в файл следующие коды:

#if !defined(MY_COSAY_HEADER)

#define MY_COSAY_HEADER

#pragma once

class CoSay : public ISay

{

//=====Класс, реализующий интерфейсы ISay, lUnknown

public:

CoSay () ;

virtual -CoSay();

// lUnknown

HRESULT _stdcall Querylnterface(REFIID riid, void** ppv);

ULONG _stdcall AddRefO;

ULONG _stdcall Release ();

// ISay

HRESULT _stdcall Say();

HRESULT _stdcall SetWord (BSTR word);

private:

//====== Счетчик числа пользователей классом

ULONG m_ref; , //====== Текст, выводимый в окно

BSTR m word;

};

#endif

Для реализации тел методов класса CoSay подключите к проекту новый файл МуСоm. срр, в который введите коды, приведенные ниже. Обратите внимание на то, как принято работать со строками текста типа BSTR:

#include "interfaces.h"

#include "MyCom.h"

//====== Произвольный ограничитель длины строк

#define MAX_LENGTH 128

CoSay::CoSay()

{

//=== Обнуляем счетчик числа пользователей класса,

//=== так как интерфейс пока не используется

m_ref = 0;

//=== Динамически создаем строку текста по умолчанию

m_word = SysAllocString (L"Hi, there."

"This is MyCom speaking");

}

CoSay::-CoSay()

{

//=== При завершении работы освобождаем память

if (m_word)

SysFreeString(m_word);

}

//====== Реализация методов lUnknown

HRESULT _stdcall CoSay::QueryInterface(REFIID riid, void** ppv)

{

//====== Стандартная логика работы с клиентом

//====== Поддерживаем только два интерфейса

*ppv = 0;

if (riid==IID_IUnknown)

*ppv = static_cast<IUnknown*>(this) ;

else if (riid==IID_ISay)

*ppv = static_cast<ISay*>(this) ;

else

return E_NOINTERFACE;

//====== Есть пользователи нашим объектом

AddRef();

return S_OK;

}

ULONG _stdcall CoSay:-.AddRef ()

{

return ++m_ref;

}

ULONG _stdcall CoSay::Release()

{

if (--m_ref==0) delete this;

return m_re f;

}

//====== Реализация методов ISay

HRESULT _stdcall CoSay::Say()

{

//=== Преобразование типов (из BSTR в char*), которое

//=== необходимо для использования MessageBox

char buff[MAX_LENGTH];

WideCharToMultiByte(CP_ACP, 0, m_word, -1, buff, MAX_LENGTH, 0, 0);

MessageBox (0, buff, "Interface ISay:", MB_OK);

return S_OK;

}

HRESULT _stdcall CoSay::SetWord(BSTR word)

{

//====== Повторное выделение памяти

SysReAllocString (&m_word, word);

freturn S_OK;

}

Класс, поддерживающий интерфейс, готов. Теперь следует сделать доступным для пользователей СОМ-объекта весь DLL-сервер, где живет ко-класс CoSay. Минимальным набором функций, которые должна экспортировать COM DLL, является реализация только одной функции DllGetClassObject. Обычно ее сопровождают еще три функции, но в данный момент мы рассматриваем лишь минимальный набор. DLL должна создать СОМ-объект и позволить работать с ним, получив, то есть записав по адресу ppv, адрес зарегистрированного интерфейса. Вы, конечно, заметили, что в предложении дважды использовано слово адрес. Именно поэтому параметр ppv имеет тип void** . Введите эту функцию в конец файла МуСот.срр:

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-реестр, который открыт всем ветрам — как случайным, так и преднамеренным воздействиям со стороны человека и программы. Однако следует согласиться с тем, что уникальная идентификация снимает проблему случайного, но весьма вероятного совпадения имен интерфейсов, разработанных в разных частях света. То же относится и к именам классов, библиотек типов и т. д.

 

Создание класса СОМ-объекта

страницы в данном разделе 
Урок 8. От сырых COM API к проекту ATL От сырых COM API к проекту ATL
Модель программирования COM Интерфейсы — основа СОМ-технологии
Уникальная идентификация объектов Как работают СОМ-серверы
Разработка сервера Создание класса СОМ-объекта
Файл описания DLL Разработка клиентского приложения
Фабрика классов Независимость от языка
Концепция маршалинга Библиотека типов
Новый проект Использование макросов COM
Разработка клиента с использованием специальных указателей Проект на основе ATL
Как работает DLL Загадочные макросы
Создание элемента типа ATL Control Двойственные интерфейсы


Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)



PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C



 
© faq.pp.ru, справочник программиста