Модель программирования Component Object Model. Разработка COM-сервера, страница 13

Просмотрите содержимое папки проекта. В случае успеха в ней должны появиться вспомогательные файлы с исходным кодом: MyComTLib_h.h, MyComTLib_i.c, MyComTLib_p.c и dlldata.c. Эти файлы помогают обеспечить взаимодействие клиента с сервером. В результате компиляции и сборки всех файлов будет сгенерирована DLL, в которой реализованы коды заглушек proxy/stub.

¨  MyComTLib_h.h содержит описания заглушек и интерфейса ISay на двух языках: С и С++. Работа с указателями vtable в языке С ведется значительно более изощренным способом, чем в языке С++. В конце файла вы можете увидеть набор макросов, которые сгенерировал MIDL для упрощения этой задачи.

¨  MyComTLib_i.c содержит идентификаторы интерфейса, его класса и библиотеки типов. Этот файл должен быть подключен к любому программному модулю. который обращается к нашему интерфейсу ISay.

¨  MyComTLib_p.c содержит исходный код заглушек (proxy/stub) для интерфейса. Он, как вы помните, обеспечивает стандартный маршалинг параметров. Код достаточно замысловатый и малопонятный, но его никогда не надо корректировать.

¨  dlldata.c содержит несколько макросов. В результате компиляции файла dlldata.c в коде DLL заглушек proxy/stub появятся функции DllMain, DllGetClassObject, DllCanUnloadNow, DllRegisterServer и DllUnRegisterServer, которые необходимы всем саморегистрирующимся DLL.

¨  Если в файле IDL имеется ключевое слово library, то по приведенной выше команде будет сгенерирована библиотека типов (двоичный TLB-файл, который вы найдете в папке Debug).

Для того, чтобы двинуться дальше вам необходимо взять некоторые файлы из папки MyCom (с предыдущим проектом типа DLL).

1.  Скопируйте и вставте в папку текущего проекта файлы MyCom.h, MyCom.cpp, MyCom.reg и MyCom.def, но не переносите файл guids.h;

2.  Подключите их к проекту. Замените в файле MyCom.cpp директиву #include "guids.h" на #include "MyComTLib_i.c", а в файл MyCom.h вставьте новую директиву #include "MyComTLib_h.h";

3.  Измените содержимое файла MyCom.def так, чтобы оно учитывало создание новой DLL.

; MyCom.def : Declares the module parameters

LIBRARY   "MYCOMTLIB.dll"

EXPORTS

DllGetClassObject PRIVATE

DllCanUnloadNow   PRIVATE

Использование макросов COM

Разработчики COM рекомендуют для повышения надежности и переносимости компонент использовать при их разработке множество макроопределений, которые вы также вынуждены будете использовать при разработке проекта на базе ATL. Например, макрос STDMETHODIMP при раскрытии заменяет спецификаторы HRESULT __stdcall. Для того, чтобы приобрести навыки использования макросов COM, мы применим их в файлах MyCom.h и MyCom.cpp. Сравнивая старую и новую версии этих файлов, вы без труда поймете смысл макроподстановок. В файл MyCom.h ведите коррекцию кодов так, как показано ниже.

#pragma once

#include "MyComTLib_h.h"

class CoSay : public ISay     // Класс, реализующий интерфейсы ISay, IUnknown

{

private:

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

BSTR m_word; // Текст, выводимый в окно

public:

CoSay();

virtual ~CoSay();

//=== Реализация обещаний IUnknown

STDMETHODIMP QueryInterface(REFIID riid, void** ppv);

STDMETHODIMP_(ULONG) AddRef();

STDMETHODIMP_(ULONG) Release();

//=== Реализация обещаний ISay

STDMETHODIMP Say();

STDMETHODIMP SetWord (BSTR word);

};

class CoSayFactory : public IClassFactory   // Фабрика классов COM DLL-сервера

{

private:

ULONG m_ref;

public:

CoSayFactory();

virtual ~CoSayFactory();

STDMETHODIMP QueryInterface(REFIID riid, void** ppv);

STDMETHODIMP_(ULONG) AddRef();

STDMETHODIMP_(ULONG) Release();

STDMETHODIMP CreateInstance (LPUNKNOWN p, REFIID r, void** pp);

STDMETHODIMP LockServer(BOOL bLock);

};

Теперь перейдите к файлу MyCom.cpp и произведите замены в соответствии с текстом, приведенным ниже.

#include "MyComTLib_i.c"

#include "MyCom.h"

ULONG gLockCount;  // Счетчик числа блокировок DLL

ULONG gObjCount; // Счетчик числа пользователей COM-объектами

CoSay::CoSay()