call_as - атрибут
Атрибут [call_as] позволяет сопоставить функцию, которую нельзя вызвать удаленно, с удаленной функцией.
[call_as (local-proc), [ , operation-attribute-list ] ] operation-name ;
-
local-proc
-
Задает определяемую операцией подпрограмму.
-
operation-attribute-list
-
Указывает один или несколько атрибутов, применяемых к операции. Разделяйте несколько атрибутов запятыми.
-
operation-name
-
Указывает именованную операцию, представленную приложению.
Возможность сопоставить функцию, которую нельзя вызвать удаленно, с удаленной функцией особенно полезна в интерфейсах с множеством типов параметров, которые не могут передаваться по сети. Вместо использования множества типов [represent_as] и [transmit_as] можно объединить все преобразования с помощью подпрограмм [call_as] . Вы предоставляете две подпрограммы [call_as] (на стороне клиента и сервера) для привязки подпрограммы между вызовами приложения и удаленными вызовами.
Атрибут [call_as] можно использовать для интерфейсов объектов. В этом случае определение интерфейса можно использовать как для локальных, так и для удаленных вызовов, так как [call_as] позволяет прозрачно сопоставлять интерфейс, к которому не удается получить удаленный доступ. Атрибут [call_as] нельзя использовать в режиме /osf .
Например, предположим, что подпрограмма f1 в интерфейсе объекта IFace требует многочисленных преобразований между вызовами пользователя и тем, что фактически передается. В следующих примерах описываются файлы IDL и ACF для интерфейса IFace.
В IDL-файле для интерфейса IFace:
[local] HRESULT f1 ( <users parameter list> )
[call_as( f1 )] long Remf1( <remote parameter list> );
В ACF для интерфейса IFace:
[call_as( f1 )] Remf1();
Это приводит к тому, что созданный файл заголовка определяет интерфейс с помощью определения f1, но также предоставляет заглушки для Remf1.
Компилятор MIDL создаст следующую Vtable в файле заголовка для интерфейса IFace:
struct IFace_vtable
{
HRESULT ( * f1) ( <users parameter list> );
/* Other vtable functions. */
};
Затем прокси-сервер на стороне клиента будет иметь типичный прокси-сервер, созданный MIDL для Remf1, в то время как заглушка на стороне сервера для Remf1 будет такой же, как и обычная заглушка, созданная MIDL:
HRESULT IFace_Remf1_Stub ( <parameter list> )
{
// Other function code.
/* instead of IFace_f1 */
invoke IFace_f1_Stub ( <remote parameter list> );
// Other function code.
}
Затем необходимо вручную закодировать две подпрограммы связи [call_as] (на стороне клиента и сервера):
HRESULT f1_Proxy ( <users parameter list> )
{
// Other function code.
Remf1_Proxy ( <remote parameter list> );
// Other function code.
}
long IFace_f1_Stub ( <remote parameter list> )
{
// Other function code.
IFace_f1 ( <users parameter list> );
// Other function code.
}
Для интерфейсов объектов это прототипы подпрограмм связи.
Для клиентской стороны:
<local_return_type> <interface>_<local_routine>_proxy(
<local_parameter_list> );
Для серверной стороны:
<remote_return_type> <interface>_<local_routine>_stub(
<remote_parameter_list> );
Для необъектных интерфейсов это прототипы подпрограмм связывания.
Для клиентской стороны:
<local_return_type> <local_routine> ( <local_parameter_list> );
Для серверной стороны:
<local_return_type> <interface>_v<maj>_<min>_<local_routine> (
<remote_parameter_list> );