Поделиться через


атрибут context_handle

Атрибут [context_handle] определяет дескриптор привязки, который хранит контекст или сведения о состоянии на сервере между удаленными вызовами процедур.

typedef [context_handle [ , type-attribute-list ] ] type-specifier declarator-list;

[context_handle [, function-attr-list ] ] type-specifier [ptr-decl] function-name(
    [ [parameter-attribute-list] ] type-specifier [declarator], ...);

[ [ function-attr-list ] ] type-specifier [ ptr-decl ] function-name(
    [context_handle [ , parameter-attribute-list ] ] type-specifier [declarator], ...);

[ void __RPC_USER context-handle-type_rundown (
  context-handle-type); ]

Параметры

type-attribute-list

Указывает один или несколько атрибутов, применяемых к типу.

описатель типа

Указывает тип указателя или идентификатор типа. Необязательная спецификация хранилища может предшествовать спецификатору типа.

declarator и declarator-list

Указывает стандартные деклараторы C, такие как идентификаторы, деклараторы указателей и деклараторы массива. Декларатор для дескриптора контекста должен содержать по крайней мере один декларатор указателя. Дополнительные сведения см. в статье Атрибуты массива и Sized-Pointer, массивы и указатели. Список деклараторов состоит из одного или нескольких деклараторов, разделенных запятыми. Идентификатор parameter-name в деклараторе функции является необязательным.

function-attr-list

Задает ноль или несколько атрибутов, применяемых к функции. Допустимые атрибуты функции: [callback], [local]; атрибут указателя [ссылка], [уникальный], или [ptr]; и атрибуты использования [string], [ignore] и [context_handle].

ptr-decl

Указывает ноль или более деклараторов указателей. Декларатор указателя совпадает с декларатором указателя, используемым в C; он создается на основе конструктора * , модификаторов, таких как far, и квалификатора const.

имя функции

Указывает имя удаленной процедуры.

parameter-attribute-list

Указывает ноль или более направленных атрибутов, атрибутов полей, атрибутов использования и атрибутов указателя, подходящих для указанного типа параметра. Разделяйте несколько атрибутов запятыми.

context-handle-type

Задает идентификатор, указывающий тип дескриптора контекста, как определено в объявлении typedef , принимающем атрибут [context_handle] . Подпрограмма запуска является необязательной.

Windows Server 2003 и Windows XP: Один интерфейс может вместить как сериализованные, так и несериализированные дескрипторы контекста, что позволяет одному методу в интерфейсе обращаться исключительно к дескриптору контекста (сериализованному), а другие методы получают доступ к этой обработке контекста в общем режиме (несериализованном). Эти возможности доступа сравнимы с механизмами блокировки чтения и записи; методы, использующие дескриптор сериализованного контекста, являются эксклюзивными пользователями (средствами записи), а методы, использующие несериализированный дескриптор контекста, являются общими пользователями (средствами чтения). Методы, которые уничтожают или изменяют состояние дескриптора контекста, должны быть сериализованы. Методы, которые не изменяют состояние дескриптора контекста, например методы, которые просто считывают из дескриптора контекста, могут быть несериализированы. Обратите внимание, что методы создания неявно сериализуются.

Комментарии

Атрибут [context_handle] может отображаться как атрибут типа определения типа IDL, как атрибут возвращаемого типа функции или атрибут параметра. При применении атрибута [context_handle] к определению типа необходимо также предоставить подпрограмму запуска контекста. Дополнительные сведения см. в разделе Подпрограмма запуска контекста сервера .

При использовании компилятора MIDL в режиме по умолчанию (/ms_ext) дескриптор контекста может быть любым типом указателя, выбранным пользователем, при условии, что он соответствует требованиям для дескрипторов контекста, описанным здесь. Данные, связанные с таким типом дескриптора контекста, не передаются по сети и должны управляться только серверным приложением. Компиляторы IDL DCE ограничивают дескрипторы контекста указателями типа void*. Поэтому эта функция недоступна при использовании параметра / osf компилятора MIDL.

Как и в случае с другими типами дескрипторов, дескриптор контекста непрозрачн для клиентского приложения, и все связанные с ним данные не передаются. На сервере дескриптор контекста выступает в качестве дескриптора для активного контекста, и все данные, связанные с типом дескриптора контекста, доступны.

Чтобы создать дескриптор контекста, клиент передает серверу указатель [out], [ref] на дескриптор контекста. (Сам дескриптор контекста может иметь значение NULL или значение, отличное от NULL , при условии, что его значение соответствует атрибутам указателя. Например, если к типу дескриптора контекста применен атрибут [ref] , он не может иметь значение NULL .) Для выполнения привязки до создания дескриптора контекста необходимо предоставить другой дескриптор привязки. Если явный дескриптор не указан, используется неявная привязка. Если атрибут [implicit_handle] отсутствует, используется автоматический дескриптор.

Удаленная процедура на сервере создает активный дескриптор контекста. Клиент должен использовать этот дескриптор контекста в качестве параметра [in] или [in, out] в последующих вызовах. В качестве дескриптора привязки можно использовать только дескриптор контекста [in], поэтому он должен иметь значение, отличное от NULL . Дескриптор контекста [in] не отражает изменения состояния на сервере.

На сервере вызываемая процедура может интерпретировать дескриптор контекста по мере необходимости. Например, вызываемая процедура может выделить хранилище кучи и использовать дескриптор контекста в качестве указателя на это хранилище.

Чтобы закрыть дескриптор контекста, клиент передает дескриптор контекста в виде аргумента [in], [out] . Сервер должен возвращать дескриптор контекста NULL , если он больше не поддерживает контекст от имени вызывающего объекта. Например, если дескриптор контекста представляет открытый файл, а вызов закрывает файл, сервер должен задать для дескриптора контекста значение NULL и вернуть его клиенту. Недопустимое значение NULL в качестве дескриптора привязки при последующих вызовах.

Дескриптор контекста действителен только для одного сервера. Если функция имеет два параметра дескриптора, а дескриптор контекста не равен NULL, дескриптор привязки должен ссылаться на одно адресное пространство.

Если функция имеет дескриптор контекста [in] или [in, out] , ее дескриптор контекста можно использовать в качестве дескриптора привязки. В этом случае неявная привязка не используется, и атрибут [implicit_handle] или [auto_handle] игнорируется.

К дескрипторам контекста применяются следующие ограничения:

  • Дескрипторы контекста не могут быть элементами массива, элементами структуры или элементами объединения. Они могут быть только параметрами.
  • Дескрипторы контекста не могут иметь атрибут [transmit_as] или [represent_as] .
  • Параметры, которые являются указателями на маркеры контекста [out] , должны быть указателями [ссылка] .
  • Дескриптор контекста [in] можно использовать в качестве дескриптора привязки и не может иметь значение NULL.
  • Дескриптор контекста[in, out может иметь значение NULL для входных данных, но только в том случае, если процедура имеет другой явный параметр дескриптора. Если нет других явных параметров дескриптора контекста, отличного от NULL , дескриптор контекста [in, out] не может иметь значение NULL.
  • Дескриптор контекста нельзя использовать с обратными вызовами.

Примеры

typedef [context_handle] void * PCONTEXT_HANDLE_TYPE; 
short RemoteFunc1([out] PCONTEXT_HANDLE_TYPE * pCxHandle); 
short RemoteFunc2([in, out] PCONTEXT_HANDLE_TYPE * pCxHandle); 
void __RPC_USER PCONTEXT_HANDLE_TYPE_rundown (PCONTEXT_HANDLE_TYPE);

См. также раздел

Массивы

auto_handle

Обратного вызова

Сброс контекста клиента

const

Дескрипторы контекста

Обрабатывать

Привязка и дескрипторы

Игнорировать

implicit_handle

В

Местных

Многопоточные клиенты и дескрипторы контекста

/ms_ext

Вне

Ptr

Ref

represent_as

RpcSsDetextClientContext

Подпрограмма запуска контекста сервера

строка

transmit_as

Typedef

Уникальный

void