Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:
char* pszName, *pszDoc;
BSTR bstrName, bstrDocString;
ITypeLib* pTypeLib;
CoInitialize(NULL);
hr=LoadRegTypeLib(LIBID_PubInProcServer, 1, 0, LANG_NEUTRAL, &pTypeLib);
if(SUCCEEDED(hr))
{
count = pTypeLib —> GetTypeInfoCount;
for (int index=-1; index < count; index++)
{
hr = pTypeLib —> GetDocumentation(index,&bstrName, &bstrDocString, NULL, NULL);
if (SUCCEEDED(hr))
{
pszName = (char*)malloc(2*SysStringLen(bstrName));
wcstombs(pszName, bstrName, 2*SysStringLen(bstrName));
cout << index << ": " << pszName;
free(pszName);
if (SysStringLen(bstrDocString) > 0)
{
pszDoc = (char*)malloc(2*SysStringLen(bstrDocString));
wcstombs(pszDoc, bstrDocString, 2*SysStringLen(bstrDocString));
cout <<": " << pszDoc;
free(pszDoc);
}
cout << endl;
SysFreeString(bstrName);
SysFreeString(bstrDocString);
}
}
pTypeLib — > Release ;
}
CoUnitialize ;
return 0;
}
Для
Функция LoadRegTypeLib загружает библиотеку типов с заданным GUID и, в случае успеха, в параметре pTypeLib возвращает указатель на интерфейс iTypeLib. В данном случае нам достаточно этого интерфейса, так как интересующая нас информация является информацией общего характера о библиотеке типов. Второй (старший номер версии) и третий (младший номер версии) параметры определяют ограничения на номер версии загружаемой библиотеки типов: загружается библиотека с указанной версией; если такой нет, то загружается библиотека, у которой старший номер версии равен запрашиваемому, а младший — максимальный из доступных и не меньше запрашиваемого. Если данное ограничение не выполняется, то возвращается ошибка. Четвертый параметр в данном случае указывает на то, что при построении описания библиотеки использовался нейтральный естественный язык.
В регистре всему этому соответствует ключ
НКЕ Y_CLASSЕS_ROOT TipeLib
{68A702C2-8283-22d5-98C7-000001223694} 1.0 0 Win32
значением которого является путь К файлу PubInProcServerTypeInfo.tlb.
В данной программе вызываются всего два метода из всего множества методов интерфейса ITypeLib:
• GetTypeInfoCount
Возвращает число описаний типов в библиотеке
• GetDocumentation
По номеру описания типа позволяет получить имя типа, его описание (helpstring), идентификатор контекста помощи и путь к файлу помощи. Подставляя NULL вместо определенного возвращаемого параметра, можно отказаться от получения соответствующей информации. Нумерация описанных в библиотеке типов начинается с нуля. Для получения информации о самой библиотеки нужно положить индекс равным — 1.
Вся строковая информация в библиотеке типов хранится в строках типа BSTR. Функция GetDocumentation сама выделяет под них память, а клиент должен ее освободить
SysFreeString(bstrName);
SysFreeString(bstrDocString);
Для перехода к ANSI строкам приходится выделять буфер подходящего размера и выполнять преобразование из BSTR в ANSI с помощью wcstombs.
Результат работы программы:
– 1: PubinProcServer: PubinProcServer with TypeLib
0: CoBook
1: IBook: Book
2: IPub: Base publication
3: CoJournal
4: IJournal: Journal
Под индексом -1 приведены имя самой библиотеки типов (как она была описана в IDL) и соответствующая строка документации (helpstring).
Под индексами от 0 до 4 идут имена типов — коклассов и их интерфейсов. Строка документации приводится только для тех из них, для которых она имеется в IDL-файле.
Таким образом, имеется возможность программным путем получать доступ к документации, включенной в библиотеку типов. Следовательно, можно организовать поиск компонент с нужной функциональностью на основе задания одного или нескольких ключевых слов.
Прозрачность местоположения
DLL сервер в суррогатном процессе
Как уже не раз говорилось ранее, один из важнейших принципов СОМ — прозрачность местоположения. Иными словами, на код клиента не должно оказывать влияние конкретное местоположение сервера (конечно при условии, что этот сервер зарегистрирован в реестре системы).
Ранее мы построили и зарегистрировали сервер в процессе клиента PubInProcServer и самого клиента PubClient. Сервер, загружаемый в процесс клиента, обладает как положительными, так и отрицательными свойствами. К положительным можно прежде всего отнести быстродействие. А к отрицательным, например, неизолированность сервера от клиента, что приводит к тому, что клиент "вылетает" при сбое сервера.
В рамках архитектуры СОМ наряду с сервером в процессе клиента можно строить локальный сервер (исполняется в отдельном процессе на машине клиента) и удаленный сервер (исполняется на удаленном компьютере). При наличии уже реализованного сервера в виде сервера в процессе клиента, его можно превратить в сервер, исполняемый вне процесса клиента, загружая в специальный процесс — DLL суррогат. Имеется стандартный DLL суррогат (dllhost.ехе), который можно использовать для этой цели.
В рамках СОМ+ использование DLL суррогата наиболее предпочтительно, так как именно в этом случае сервер сможет использовать все сервисы, предоставляемые СОМ+. Однако, при этом необходимо конфигурировать сервер, определив ряд связанных с ним атрибутов в новой структуре данных — каталоге. Эти вопросы будут рассмотрены позже при изучении СОМ+.
Итак, далее мы рассмотрим размещение сервера PubInProcServer в суррогатном процессе.
Для размещения DLL сервера в суррогатном процессе достаточно сделать несколько дополнительных настроек в реестре, связанных с идентификатором приложения — AppID.