Создание класса СОМ-объекта
Подключите к проекту новый файл 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; }