nTitleLength = SysStringLen(m_bstrTitle);
pszTitle = (char*)malloc(2*nTitleLength);
pszText = (char*)malloc(2*nTitleLength + 50);
wcstombs(pszTitle, m_bstrTitle, 2*nTitleLength);
sprintf(pszText, "Journal\n\nTitle : %s\nYear : %d\nNumber :
%d\n", pszTitle, m_nYear, m_nNumber);
*pbstrInfo = SysAllocStringLen(NULL, 2*strlen(pszText));
mbstowcs(*pbstrInfo, pszText, 2*strlen(pszText));
free(pszTitle);
free(pszText);
return S_OK;
}
Теперь, когда коклассы CoBook и CoJournal реализованы, им следует присвовить GUID и добавить соответствующую
информацию в файл
iid.h. Вот последняя версия этого файла
// GUID для всех интерфейсов и классов
// {9A5DE9A0-7225-11d5-98C7-000001223694}
DEFINE_GUID(IID_IPub,
0x9a5de9a0, 0x7225, 0x11d5,
0x98, 0xc7, 0x0, 0x0, 0x1, 0x22, 0x36, 0x94);
// {9A5DE9A1-7225-11d5-98C7-000001223694}
DEFINE_GUID(IID_IBook,
0x9a5de9a1, 0x7225, 0x11d5,
0x98, 0xc7, 0x0, 0x0, 0x1, 0x22, 0x36, 0x94);
// {9A5DE9A2-7225-11d5-98C7-000001223694}
DEFINE_GUID(IID_IJournal,
0x9a5de9a2, 0x7225, 0x11d5,
0x98, 0xc7, 0x0, 0x0, 0x1, 0x22, 0x36, 0x94);
// {49F00760-7238-11d5-98C7-000001223694}
DEFINE_GUID(CLSID_CoBook,
0x49f00760, 0x7238, 0x11d5,
0x98, 0xc7, 0x0, 0x0, 0x1, 0x22, 0x36, 0x94);
// {49F00761-7238-11d5-98C7-000001223694}
DEFINE_GUID(CLSID_CoJournal,
0x49f00761, 0x7238, 0x11d5,
0x98, 0xc7, 0x0, 0x0, 0x1, 0x22, 0x36, 0x94);
Обратите внимание, что имя идентификатора кокласса стандартно формируется следующим образом - префикс CLSID_, за
которым следует имя кокласса. Например,
CLSID_CoBook.
Фабрики классов
Теперь возникает важный вопрос - как клиент может создавать COM объекты CoBook и CoJournal?
Два важных принципа COM:
z Независимость от языка
В соответствии с идеологией модели COM, классы COM (коклассы) могут реализовываться на различных языках и должны
храниться в бинарном виде (dll или exe файл). Клиент может быть реализован на любом из поддерживающих модель COM
языке и, следовательно, должен иметь возможность создавать (активизировать) COM объект не используя каких-либо
специфических для данного языка методов, а
с помощью специального стандартного интерфейса.
z Прозрачность местоположения сервера
Имеется три места, где может размещаться COM сервер:
{ В процессе клиента
Этот способ обеспечивает самую быструю связь клиента и сервера (который реализуется в виде dll). Но есть и
проблемы. Например, при ошибке в сервере ``вылетает'' весь процесс (т.е. и клиент).
{ Вне процесса клиента, но на одной с ним машине
Это так назывемая локальная связь (обычно используется exe-сервер). Она обеспечивает надежность (при ошибках в
сервере клиент не гибнет), но необходима организация передачи данных между клиентом и сервером через границы
процессов. Это COM берет на себя, обеспечивая кодирование, передачу и декодирование данных. При этом
создаются
прокси объект в процессе клиента и заглушка в процессе сервера. Прокси имитирует для клиента сервер, а заглужка
имитирует для сервера клиента. В связи с этим код клиента не зависит от того, где располагается сервер. Все
преобразование данных и их пересылка осуществляется парой прокси-заглушка. Коммутация прокси и заглушки
основана
на протоколе упрощенного удаленного вызова процедур (LRPC - Lightweight Remote Procedure Call).
{ На удаленной машине
При этом связь наиболее медленная. Архитектура похожа на архитектуру, описанную в предыдущем пункте, только
вместо LRPC используется RPC - протокол удаленного вызова процедур.
Заметим, что клиент не обязан знать, где именно расположен используемый сервер. Код клиента не меняется при
изменении местоположения сервера. Более того, сервер может располагаться в нескольких местах, и
по просьбе клиента