-->

Сущность технологии СОМ. Библиотека программиста

На нашем литературном портале можно бесплатно читать книгу Сущность технологии СОМ. Библиотека программиста, Бокс Дональд-- . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Сущность технологии СОМ. Библиотека программиста
Название: Сущность технологии СОМ. Библиотека программиста
Дата добавления: 16 январь 2020
Количество просмотров: 276
Читать онлайн

Сущность технологии СОМ. Библиотека программиста читать книгу онлайн

Сущность технологии СОМ. Библиотека программиста - читать бесплатно онлайн , автор Бокс Дональд

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

1 ... 30 31 32 33 34 35 36 37 38 ... 118 ВПЕРЕД
Перейти на страницу:

Под одним из этих ключей будет сохранен список локальных CLSID, для каждого CLSID – свой подключ. Например, класс Gorilla, использовавшийся ранее в этой главе, мог бы иметь по всей машине запись по подключу [2]:

[HKCRCLSID{571F1680-CC83-11d0-8C48-0080C73925BA}]

@="Gorilla"

Для обеспечения локальной активации объектов Gorilla запись для CLSID Gorilla в реестре должна иметь подключ, показывающий, какой файл содержит исполняемый код для методов класса. Если сервер упакован как DLL, то требуется такая запись:

[HKCRCLSID{571F1680-CC83-11d0-8C48-0080C73925BA}InprocServer32]

@="C:ServerOfTheApes.dll"

Чтобы показать, что код упакован в исполняемом файле, требуется такая запись:

[HKCRCLSID{571F1680-CC83-11d0-8C48-0080C73925BA}LocalServer32]

@="С:ServerOfTheApes.exe"

Допустимо обеспечивать обе записи и позволить клиенту выбирать местоположение, исходя из требований времени задержки и устойчивости. Для поддержки функции ProgIDFromCLSID необходимо указать такой подключ:

[HKCRCLSID{571F1680-CC83-11d0-8C48-0080C73925BA}ProgID]

@="Apes.Gorilla.1"

Наоборот, для поддержки функции CLSIDFromProgID требуются следующие величины:

[HKCRApes.Gorilla.1] @="Gorilla" [HKCRApes.Gorilla.1CLSID]

@="{571F1680-CC83-11d0-8C48-0080C73925BA}

Программные идентификаторы (ProgID) не являются обязательными, но они рекомендуются, чтобы в тех средах, которые не могут просто копировать необработанные CLSID, тоже можно было осуществлять вызовы на активацию.

Все стандартно реализованные серверы СОМ поддерживают саморегистрацию. Для внутрипроцессного сервера это означает, что DLL должен экспортировать известные функции

STDAPI DllRegisterServer(void);

STDAPI DllUnregisterServer(void);

Отметим, что STDAPI является просто макросом, индицирующим, что функция возвращает НRESULT и использует стандартное соглашение СОМ по вызову глобальных функций. Эти подпрограммы должны быть явно экспортированы с использованием или файла определения модуля, или переключателей компоновщика, или директив компилятора. Эти подпрограммы используются хранилищем классов Class Store для конфигурирования локального кэша после загрузки файла на машину клиента. Кроме Class Store эти известные подпрограммы используются различными средами (например, Microsoft Transaction Server, ActiveX Code Download, а также различными инсталляционными программами) для инсталляции или деинсталляции серверов на хост-машинах. В Win32 SDK включена утилита REGSVR32.EXE, которая может инсталлировать или деинсталлировать внутрипроцессный сервер СОМ с использованием этих известных экспортированных функций.

Реализации внутрипроцессных серверов DllRegisterServer и DllUnregisterServer должны запросить реестр на добавление или удаление соответствующих ключей, преобразующих CLSID и ProgID сервера в файловые имена сервера. Хотя существуют различные способы реализации этих подпрограмм, наиболее гибким и эффективным из них является создание строковой таблицы, содержащей соответствующие ключи, названия величин, сами величины и простое перечисление всех записей в таблице, путем вызова RegSetValueEx для инсталляции и RegDeleteKey для деинсталляции. Чтобы осуществить регистрацию, основанную на этой технологии, сервер может просто задать массив строк размером Nx3 , где каждый ряд массива содержит строки для использования в качестве ключей, имена величин и величины:

const char *gRegTable[][3] = {

// format is { key, value name, value }

{

«CLSID\{571F1680-CC83-11d0-8C48-0080C73925BA}», 0, «Gorilla»

},

{

"CLSID\{571F1680-CC83-11d0-8C48-0080C73925BA}

\InprocServer32",0, (const char*)-1

// rogue value indicating file name

// нестандартное значение, указывающее имя файла

},

{

«CLSID\{571F1680-CC83-11d0-8C48-0080C73925BA}\ProgID», 0, «Ареs.Gorilla.1»

},

{

«Apes.Gorillа.1», 0, «Gorilla»

},

{

«Apes.Gorilla.1\CLSID», 0, «{571F1680-CC83-11d0-8C48-0080C73925BA}»

},

};

Имея эту таблицу, весьма несложно осуществить реализацию DllRegisterServer:

STDAPI DllRegisterServer(void)

{

HRESULT hr = SOK;

// look up server's file name

// ищем имя файла сервера

char szFileName[MAXPATH];

GetModuleFileNameA(ghinstDll, szFileName, MAXPATH);

// register entries from table

// регистрируем записи из таблицы

int nEntries = sizeof(gRegTable)/sizeof(*gRegTable);

for (int i = 0; SUCCEEDED(hr) && i < nEntries; i++)

{

const char *pszKeyName = gRegTable[i][0];

const char *pszValueName = gRegTable[i][1];

const char *pszvalue = gRegTable[i][2];

// map rogue value to module file name

// переводим нестандарное значение в имя файла модуля

if (pszValue == (const char*)-1) pszValue = szFileName;

HKEY hkey;

// create the key

// создаем ключ

long err = RegCreateKeyA(HKEYCLASSESROOT, pszKeyName, &hkey);

if (err == ERRORSUCCESS)

{

// set the value

// присваиваем значение

err = RegSetValueExA(hkey, pszVvalueName, 0, REGSZ, (const BYTE*) pszValue, (strlen(pszValue) + 1));

RegCloseKey(hkey);

}

if (err != ERRORSUCCESS)

{

// if cannot add key or value, back out and fail

// если невозможно добавить ключ или значение, то откат и сбой

DllUnregisterServer();

hr = SELFREGECLASS;

}

}

return hr;

}

Соответствующая DllUnregisterServer будет выглядеть так:

STDAPI DllUnregisterServer(void)

{

HRESULT hr = SOK;

int nEntries = sizeof(gRegTable)/sizeof(*gRegTable);

for (int i = nEntries – 1; i >= 0; i-)

{

const char *pszKeyName = gRegTable[i][0];

long err = RegDeleteKeyA(HKEYCLASSESROOT, pszKeyName);

if (err != ERRORSUCCESS) hr = SFALSE; }

return hr;

}

Отметим, что реализация DllUnregisterServer просматривает таблицу с конца, начиная с последней входной точки. Делается это для преодоления ограничения RegDeleteKey, в котором разрешаются только такие ключи, у которых нет подключей, подлежащих удалению. Реализация DllUnregisterServer требует такой организации таблицы, чтобы все подключи каждого ключа появлялись в таблице после входа родительского ключа.

Так как СОМ преобразует CLSID в данный файл реализации, то для объявления в СОМ относящихся к серверу объектов класса необходимо использовать определенные стандартные методики. Для сервера, основанного на исполняемой программе, в СОМ предусмотрены явные API-функции для связывания объектов класса с их CLSID . Эти API-функции мы будем подробно обсуждать в главе 6. Для сервера, основанного на DLL, DLL должна экспортировать известную функцию, которая будет вызываться с помощью CoGetClassObject, когда потребуется объект класса. Эту функцию необходимо экспортировать с использованием файла определения модулей, причем она должна иметь следующий вид:

1 ... 30 31 32 33 34 35 36 37 38 ... 118 ВПЕРЕД
Перейти на страницу:
Комментариев (0)
название