Простой COM – клиент

Обычно разговор о COM – модели начинают с довольно пространного изложения теории COM – сервера. Но я начну с описания клиента. Кажется, этот подход не лишен логики. Действительно, большинство программистов сталкивается или столкнется с написанием именно клиента.

Для простоты наш клиент будет консольной программой. Для создания консольной программы выберем тип проекта Win32 и пустой проект. Мы используем интерфейс, который в дальнейшем нам предстоит создать.

//*********************
//для вызова API-функции поддержки COM

#include <windows.h>
//для использования в программе IUnknown
#include <initguid.h>
//*********************
//идентификатор интерфейса
// {9577908B-192F-4f02-8B84-3B737EB520A1}

DEFINE_GUID(IID_IMes, 0x9577908b, 0x192f, 0x4f02, _
0x8b, 0x84, 0x3b, 0x73, 0x7e, 0xb5, 0x20, 0xa1);

//идентификатор класса
// {0CF6CAA4-71E1-48ce-8FCB-5E50D22E45B3}

DEFINE_GUID(CLSID_Mes,0xcf6caa4, 0x71e1, 0x48ce, _
0x8f, 0xcb, 0x5e, 0x50, 0xd2, 0x2e, 0x45, 0xb3);

//объявление интерфейса
interface IMes :public IUnknown
{
//метод выводит на экран окно с сообщением s
virtual HRESULT _stdcall mes(char* s)=0;
};

int main(int argc, char*argv[])
{
//инициализировать COM
CoInitialize(0);
//определить указатель на интерфейс
IMes*pmes;
//получить интерфейс по двум идентификаторам
HRESULT h=CoGetClassObject(CLSID_Mes, _
CLSCTX_INPROC_SERVER, 0, IID_IMes, (void**)&pmes);
//проверить результат выполнения функции
if(FAILED(h))
{
MessageBox(0,"","",MB_OK);
CoUninitialize();
return -1;
}
//вызвать метод полученного интерфейса
pmes->mes("строка в COM-объекте");
//освободить интерфейс
pmes->Release();
//закрыть COM
CoUninitialize();
return 0;
}

Программа прокомментирована, и, хотя возможно, вам не всё понятно в ней, написать программу использования другого интерфейса не должно составить большого труда. Обращаем ваше внимание, что в программе использованы два идентификатора. Это, несомненно, слабое место данного клиентского приложения.

Обратим также ваше внимание на функцию CoGetClassObject. Второй параметр в этой функции определяет то, где может находиться COM – сервер. Вот возможные значения этого параметра:

  • CLSCTX_INPROC_SERVER – клиент работает с компонентами, реализованными в динамической библиотеке и исполняемыми в одном с ним процессе.
  • CLSCTX_INPROC_HANDLER – клиент работает с компонентами внутри процесса.
  • CLSCTX_LOCAL_SERVER – клиент работает с компонентами, которые выполняются в другом процессе, но на той же самой машине. Локальные серверы реализуются в EXE – файлах.
  • CLSCTX_REMOTE_SERVER – клиент может работать с компонентами на другой машине.