На этом шаге мы рассмотрим содержимое заголовочных файлов СОМ-сервера.
На 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".
На следующем шаге мы рассмотрим алгоритм создания такого приложения.