Разработка интерфейса с использованием дескрипторов контекста
Как правило, дескриптор контекста создается путем указания атрибута [context_handle] в определении типа в IDL-файле. Определение типа также неявно указывает подпрограмму запуска контекста, которую необходимо указать. Если обмен данными между клиентом и сервером прерывается, во время выполнения сервера вызывается эта подпрограмма для выполнения любой необходимой очистки. Дополнительные сведения о подпрограммах выполнения контекста см. в разделе Подпрограмма запуска контекста сервера.
Интерфейс, использующий дескриптор контекста, должен иметь дескриптор привязки для начальной привязки, который должен выполняться до того, как сервер сможет вернуть дескриптор контекста. Для создания привязки и установления контекста можно использовать автоматический, неявный или явный дескриптор привязки.
Дескриптор контекста должен иметь тип void * или тип, разрешающийся в void *. Серверная программа приводит его к требуемому типу.
Примечание
Использование [in, out] для параметров дескриптора контекста не рекомендуется, за исключением подпрограмм, которые закрывают дескриптора контекста. Если используются параметры контекстных дескрипторов, помеченные [in, out], не передайте серверу дескриптор контекста null или неинициализированный дескриптор контекста от клиента. Вместо этого следует передать указатель NULL на дескриптор контекста. Обратите внимание, что параметры дескриптора контекста с пометкой [in] не принимают указатели NULL .
В следующем фрагменте примера определения интерфейса показано, как распределенное приложение может использовать дескриптор контекста, чтобы открыть сервер и обновить файл данных для каждого клиента.
Интерфейс должен содержать удаленный вызов процедуры, чтобы инициализировать дескриптор и задать для него значение, отличное от NULL . В этом примере эта операция выполняется с помощью функции RemoteOpen. Он задает дескриптор контекста с атрибутом направления [out]. Кроме того, можно вернуть дескриптор контекста в качестве возвращаемого значения процедуры. Однако в этом примере мы передадим дескриптор контекста через список параметров.
В этом примере сведения контекста являются дескриптором файла. Он отслеживает текущее расположение в файле. Интерфейс упаковывает дескриптор файла в качестве дескриптора контекста и передает его в качестве параметра для удаленных вызовов процедур. Структура содержит имя файла и дескриптор файла.
/* file: cxhndl.idl (fragment of interface definition file) */
typedef [context_handle] void * PCONTEXT_HANDLE_TYPE;
typedef [ref] PCONTEXT_HANDLE_TYPE * PPCONTEXT_HANDLE_TYPE;
short RemoteOpen([out] PPCONTEXT_HANDLE_TYPE pphContext,
[in, string] unsigned char * pszFile);
void RemoteRead(
[in] PCONTEXT_HANDLE_TYPE phContext,
[out, size_is(cbBuf)] unsigned char achBuf[],
[in, out] short *pcbBuf);
short RemoteClose([in, out] PPCONTEXT_HANDLE_TYPE pphContext);
Функция RemoteOpen создает допустимый дескриптор контекста, отличный от NULL . Он передает дескриптор контекста клиенту. Последующие вызовы удаленных процедур, например RemoteRead, используют дескриптор контекста в качестве указателя.
Помимо удаленной процедуры, которая инициализирует дескриптор контекста, интерфейс должен содержать процедуру, которая освобождает контекст сервера и устанавливает для дескриптора контекста значение NULL. В предыдущем примере эта операция выполняется с помощью функции RemoteClose.