На этом шаге мы рассмотрим содержимое заголовочных файлов СОМ-сервера.
На 181 шаге мы узнали, как MIDL-компилятор формирует заголовочные файлы, которые делают интерфейс СОМ-сервера и GUID доступными клиентам, написанным на C++ и С. Исходные файлы компонента Encoder называются EncodeServer.h и Encode Server_i.с.
В EncodeServer_i.c имеется следующий код с объявлением GUID компонента Encoder в качестве констант, легких для восприятия и ввода:
const IID IID_IEncoder = {0xE24F453C,0x9B8B,0x40ED, {0x92,0xA2,0xBC,0x57,0x59,0x44,0x71,0xC9}}; const IID LIBID_ENCODESERVERLib = {0xEECD8638,0xCFC3,0x43F8, {0xA1,0x0C,0xD4,0xC9,0x57,0x3E,0x26,0xDD}}; const CLSID CLSID_Encoder = {0x9DBB482D,0x4600,0x43F4, {0xA9,0x6E,0xAE,0xF8,0xF6,0x00,0x57,0x4E}};
Типы IID и CLSID определены в этом файле чуть раньше в вид структур С, служащих для представления GUID.
Примерно в середине файла EncodeServer.h имеется следующее объявление C++ (для простоты комментарии удалены):
MIDL_INTERFACE("E24F453C-9B8B-40ED-92A2-BC57594471C9") IEncoder : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE EncodeString( const BSTR instring, BSTR __RPC_FAR *outstring) = 0; virtual HRESULT STDMETHODCALLTYPE get_Key( short __RPC_FAR *pVal) = 0; virtual HRESULT STDMETHODCALLTYPE put_Key( short newVal) = 0; };
Здесь определяется абстрактный класс IEncoder (производный от абстрактного класса IUnknown), содержащий функции-члены, соответствующие методам СОМ-интерфейса IEncoder. В макросе MIDL_INTERFACE используется определенный Microsoft оператор объявления __declspec(uuid()), служащий для создания связи между классом и GUID интерфейса. Обратное преобразование - получение GUID по имени класса - Вы можете выполнить, воспользовавшись ключевым словом __uuidof().
Клиентские приложения применяют определения этих заголовочных файлов для создания указателей на класс IEncoder, передаваемых в функцию CoCreateInstance(). Это продемонстрировано в следующем примере:
IEncoder * pServer;
HRESULT hr = ::CoCreateInstance(CLSID_Encoder, NULL,
CLSCTX_INPROC_SERVER,
IID_IEncoder,
(void **) &pServer);
В случае успешного создания СОМ-объекта Encoder в переменяй pServer возвращается указатель на его таблицу vtable. В дальнейшем он Вам пригодится для вызова методов IEncoder.
Для демонстрации работы заголовочных файлов EncodeServer.h и EncodeServer_i.c разработаем простое консольное приложение EncodeHello, использующее Encoder для вывода строки "Hello World".
На следующем шаге мы рассмотрим алгоритм создания такого приложения.