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

Тут можно читать онлайн Дональд Бокс - Сущность технологии СОМ. Библиотека программиста - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Питер, год 2001. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Сущность технологии СОМ. Библиотека программиста
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2001
  • Город:
    СПб
  • ISBN:
    5-318-00058-4
  • Рейтинг:
    4/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

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

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

Интервал:

Закладка:

Сделать

HRESULT CoResumeClassObjects(void);

CoResumeClassObjects делает следующее. Во-первых, она помечает все отложенные объекты класса как легальные для использования. Во-вторых, она посылает SCM единственное сообщение, информируя его, что все ранее отложенные объекты класса теперь являются доступными в серверном процессе. Это сообщение обладает огромной силой, так как при его получении обновляется таблица класса SCM по всей машине и сразу для всех классов, зарегистрированных вызывающим объектом.

Получив три только что описанные API-функции, легко создать серверный процесс, экспортирующий один или более классов. Ниже приводится простая программа, которая экспортирует три класса из МТА сервера:

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

// define a singleton class object for each class

// определяем синглетон для каждого класса

static GorillaClass s_gorillaClass; static OrangutanClass s_orangutanClass;

static ChimpClass s_chimpClass; DWORD rgdwReg[3];

const DWORD dwRegCls = REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED;

const DWORD dwClsCtx = CLSCTX_LOCAL_SERVER;

// enter the MTA

// входим в МТА

HRESULT hr = GoInitializeEx(0, COINIT_MULTITHREADED);

assert(SUCCEEDED(hr));

// register class objects with СОM library's class table

// регистрируем объекты класса с помощью

// таблицы класса библиотеки COM

hr = CoRegisterClassObject(CLSID_Gorilla, &s_gorillaClass, dwClsCtx, dwRegCls, rgdwReg);

assert(SUCCEEDED(hr));

hr = CoRegisterClassObject(CLSID_Orangutan, &s_orangutanClass, dwClsCtx, dwRegCls, rgdwReg + 1);

assert(SUCCEEDED(hr)) ;

hr = CoRegisterClassObject(CLSID_Chimp, &s_chimpClass, dwClsCtx, dwRegCls, rgdwReg + 2);

assert(SUCCEEDED(hr));

// notify the SCM

// извещаем SCM

hr = CoResumeClassObjects();

assert(SUCCEEDED(hr));

// keep process alive until event is signaled

// сохраняем процессу жизнь, пока событие не наступило

extern HANDLE g_heventShutdown; WaitForSingleObject(g_heventShutdown, INFINITE);

// remove entries from COM library's class table

// удаляем элементы из таблицы класса библиотеки COM

for (int n = 0; n < 3; n++)

CoRevokeClassObject(rgdwReg[n]);

// leave the MTA

// покидаем MTA CoUninitialize();

return 0;

}

В данном фрагменте кода предполагается, что событие (Win32 Event object) будет инициализировано где-нибудь еще внутри процесса таким образом:

HANDLE g_heventShutdown = CreateEvent(0, TRUE, FALSE, 0);

Имея данное событие, сервер может быть мирно остановлен с помощью вызова API-функции SetEvent :

SetEvent(g_heventShutdown);

которая запустит последовательность выключения в главном потоке. Если бы сервер был реализован как сервер на основе STA, то главный поток должен был бы вместо ожидания события Win32 Event запустить конвейер обработки оконных сообщений ( windows message pump ). Это необходимо для того, чтобы позволить поступающим ORPC-запросам входить в апартамент главного потока.

Снова о времени жизни сервера

В примере, показанном в предыдущем разделе, не было точно показано, как и когда должен прекратить работу серверный процесс. В общем случае серверный процесс сам контролирует свое время жизни и может прекратить работу в любой выбранный им момент. Хотя для серверного процесса и допустимо неограниченное время работы, большинство из них предпочитают выключаться, когда не осталось неосвобожденных ссылок на их объекты или объекты класса. Это аналогично стратегии, используемой большинством внутрипроцессных серверов в их реализации DllCanUnloadNow . Напомним, что в главе 3 говорилось, что обычно сервер реализует две подпрограммы, вызываемые в качестве интерфейсных указателей, которые запрашиваются и освобождаются внешними клиентами:

// reasons to remain loaded

// причины оставаться загруженными

LONG g_cLocks = 0;

// called from AddRef + IClassFactory::LockServer(TRUE)

// вызвано из AddRef + IClassFactory::LockServer(TRUE)

void LockModule(void) {

InterlockedIncrement(&g_cLocks);

}

// called from Release + IClassFactory::LockServer(FALSE)

// вызвано из Release + IClassFactory::LockServer(FALSE)

void UnlockModule(void) {

InterlockedDecrement(&g_cLocks);

}

Это сделало реализацию DllCanUnloadNow предельно простой:

STDAPI DllCanUnloadNow() { return g_cLocks ? S_FALSE : S_OK; }

Подпрограмму DllCanUnloadNow нужно вызывать в случаях, когда клиент решил «собрать мусор» в своем адресном пространстве путем вызова CoFreeUnusedLibraries для освобождения неиспользуемых библиотек.

Имеются некоторые различия в том, как ЕХЕ-серверы прекращают работу серверов. Во-первых, обязанностью серверного процесса является упреждающее инициирование процесса своего выключения. В отличие от внутрипроцессных серверов, здесь не существует «сборщика мусора», который запросил бы внепроцессный сервер, желает ли он прекратить работу. Вместо этого серверный процесс должен в подходящий момент явно запустить процесс своего выключения. Если для выключения сервера используется событие Win32 Event, то процесс должен вызвать API-функцию SetEvent :

void UnlockModule(void) {

if (InterlockedDecrement(&g_cLocks) ==0)

{

extern HANDLE g_heventShutdown;

SetEvent(g_heventShutdown);

}

}

Если вместо серверного основного потока обслуживается очередь событий Windows MSG , то для прерывания цикла обработки сообщений следует использовать некоторые из API-функций. Проще всего использовать PostThreadMessage для передачи в основной поток сообщения WM_QUIT :

void UnlockModule(void) {

if (InterlockedDecrement(&g_cLocks) == 0) {

extern DWORD g_dwMainThreadID;

// set from main thread

// установлено из основного потока

PostThreadMessage(g_dwMainThreadID, WNLQUIT, 0, 0);

}

}

Если серверный процесс на основе STA знает, что он никогда не будет создавать дополнительные потоки, то он может использовать несколько более простую API-функцию PostQuitMessage :

void UnlockModule(void) {

if (InterlockedDecrement(&g_cLocks) == 0) PostQuitMessage(0);

}

Этот способ работает только при вызове из главного потока серверного процесса.

Второе различие в управлении временем жизни внутрипроцессного и внепроцессного сервера связано с тем, что должно поддерживать сервер в загруженном или работающем состоянии. В случае внутрипроцессного сервера такой силой обладают неосвобожденные ссылки на объекты и неотмененные вызовы IClassFactory::LockServer(TRUE) . Неосвобожденные ссылки на объекты необходимо рассмотреть в контексте внепроцессного сервера.

Безусловно, сервер должен оставаться доступным до тех пор, пока внешние клиенты имеют неосвобожденные ссылки на объекты класса сервера. Для внутрипроцессного сервера это реализуется следующим образом:

STDMETHODIMP_(ULONG) MyClassObject::AddRef(void) {

LockModule();

// note outstanding reference

// отмечаем неосвобожденную ссылку

return 2;

// non-heap-based object

// объект, размещенный не в «куче»

}

STDMETHODIMP_(ULONG) MyClassObject::Release(void) {

UnlockModule();

// note destroyed reference

// отмечаем уничтоженную ссылку

return 1;

// non-heap-based object

// объект, размещенный не в «куче»

}

Такое поведение является обязательным, поскольку если DLL выгружается, несмотря на оставшиеся неосвобожденные ссылки на объекты класса, то даже последующие вызовы метода Release приведут клиентский процесс к гибели.

К сожалению, предшествующая реализация AddRef и Release не годится для внепроцессных серверов. Напомним, что после входа в апартамент COM первое, что делает типичный внепроцессный сервер, – регистрирует свои объекты класса с помощью библиотеки COM путем вызова CoRegisterClassObject . Тем не менее, пока таблица класса сохраняет объект класса, существует по меньшей мере одна неосвобожденная ссылка COM на объект класса. Это означает, что после регистрации своих объектов класса счетчик блокировок всего модуля будет отличен от нуля. Эти самоустановленные ( self-imposed ) ссылки не будут освобождены до вызова серверным процессом CoRevokeClassObject . К сожалению, типичный серверный процесс не вызовет CoRevokeClassObject до тех пор, пока счетчик блокировок всего модуля не достигнет нуля, что означает, что серверный процесс никогда не прекратится.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Дональд Бокс читать все книги автора по порядку

Дональд Бокс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x