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

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-запросам входить в апартамент главного потока.

<p>Снова о времени жизни сервера</p>

В примере, показанном в предыдущем разделе, не было точно показано, как и когда должен прекратить работу серверный процесс. В общем случае серверный процесс сам контролирует свое время жизни и может прекратить работу в любой выбранный им момент. Хотя для серверного процесса и допустимо неограниченное время работы, большинство из них предпочитают выключаться, когда не осталось неосвобожденных ссылок на их объекты или объекты класса. Это аналогично стратегии, используемой большинством внутрипроцессных серверов в их реализации 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) {

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных