Registrar interfaces

En esta sección se presenta una explicación detallada del proceso de registro de una interfaz RPC.

La información de esta sección se presenta en los temas siguientes:

Funciones de registro de interfaz

Los servidores registran sus interfaces mediante una llamada a la función RpcServerRegisterIf . Los programas de servidor complejos suelen admitir más de una interfaz. Las aplicaciones de servidor deben llamar a esta función una vez para cada interfaz que admitan.

Además, los servidores pueden admitir varias versiones de la misma interfaz, cada una con su propia implementación de las funciones de la interfaz. Si el programa de servidor lo hace, debe proporcionar un conjunto de puntos de entrada. Un punto de entrada es una rutina de administrador que envía llamadas para una versión de una interfaz. Debe haber un punto de entrada para cada versión de la interfaz. El grupo de puntos de entrada se denomina vector de punto de entrada. Para obtener más información, consulte Vectores de punto de entrada.

Además de la función estándar RpcServerRegisterIf, RPC también admite otras funciones de registro de interfaz. La función RpcServerRegisterIf2 amplía las funcionalidades de RpcServerRegisterIf al permitirle especificar un conjunto de marcas de registro (vea Marcas de registro de interfaz), el número máximo de solicitudes de llamada a procedimiento remoto simultáneas que el servidor puede aceptar y el tamaño máximo en bytes de bloques de datos entrantes.

La biblioteca RPC también contiene una función denominada RpcServerRegisterIfEx. Al igual que la función RpcServerRegisterIf , esta función registra una interfaz. El programa de servidor también puede usar esta función para especificar un conjunto de marcas de registro (consulte Marcas de registro de interfaz), el número máximo de solicitudes simultáneas de llamada a procedimiento remoto que el servidor puede aceptar y una función de devolución de llamada de seguridad.

Las funciones RpcServerRegisterIf, RpcServerRegisterIfEx y RpcServerRegisterIf2 establecen valores en la tabla del Registro de interfaz interna. Esta tabla se usa para asignar los UUID de interfaz y los UUID de objeto a un administrador EPV. El administrador EPV es una matriz de punteros de función que contiene exactamente un puntero de función para cada prototipo de función en la interfaz especificada en el archivo IDL.

Para obtener información sobre cómo proporcionar varios EPV para proporcionar varias implementaciones de la interfaz, consulte Implementaciones de varias interfaces.

La biblioteca en tiempo de ejecución usa la tabla del Registro de interfaz (establecida por llamadas a la función RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2) y la tabla del Registro de objetos (establecida por llamadas a la función RpcObjectSetType) para asignar uuID de interfaz y objeto al puntero de función.

Cuando desee que el programa de servidor quite una interfaz del registro de biblioteca en tiempo de ejecución rpc, llame a la función RpcServerUnregisterIf . Después de quitar la interfaz del Registro, la biblioteca en tiempo de ejecución rpc ya no aceptará nuevas llamadas para esa interfaz.

Vectores de punto de entrada

El vector de punto de entrada del administrador (EPV) es una matriz de punteros de función que apuntan a implementaciones de las funciones especificadas en el archivo IDL. El número de elementos de la matriz corresponde al número de funciones especificadas en el archivo IDL. RPC admite varios vectores de punto de entrada que representan varias implementaciones de las funciones especificadas en la interfaz.

El compilador MIDL genera automáticamente un tipo de datos EPV de administrador para su uso en la construcción de EPV de administrador. El tipo de datos se denomina if-name**_SERVER_EPV**, donde if-name especifica el identificador de interfaz en el archivo IDL.

El compilador MIDL crea e inicializa automáticamente un EPV de administrador predeterminado en la suposición de que existe una rutina de administrador del mismo nombre para cada procedimiento de la interfaz y se especifica en el archivo IDL.

Cuando un servidor ofrece varias implementaciones de la misma interfaz, el servidor debe crear un administrador adicional EPV para cada implementación. Cada EPV debe contener exactamente un punto de entrada (dirección de una función) para cada procedimiento definido en el archivo IDL. La aplicación de servidor declara e inicializa una variable EPV de administrador de tipo if-name**_SERVER_EPV** para cada implementación adicional de la interfaz. Para registrar los EPV, llama a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 una vez para cada tipo de objeto que admite.

Cuando el cliente realiza una llamada a procedimiento remoto al servidor, el EPV que contiene el puntero de función se selecciona en función del UUID de la interfaz y del tipo de objeto. El tipo de objeto se deriva del UUID del objeto mediante la función object-inquiry o la asignación controlada por tablas controlada por RpcObjectSetType.

EPV de administrador

De forma predeterminada, el compilador MIDL usa los nombres de procedimiento del archivo IDL de una interfaz para generar un administrador EPV, que el compilador coloca directamente en el código auxiliar del servidor. Este EPV predeterminado se inicializa estáticamente con los nombres de procedimiento declarados en la definición de la interfaz.

Para registrar un administrador mediante el EPV predeterminado, especifique NULL como valor del parámetro MgrEpv en una llamada a la función RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 . Si los nombres de rutina utilizados por un administrador corresponden a los de la definición de interfaz, puede registrar este administrador mediante el EPV predeterminado de la interfaz generada por el compilador MIDL. También puede registrar un administrador mediante un EPV que proporciona la aplicación de servidor.

Un servidor puede (y a veces debe) crear y registrar un EPV de administrador que no sea NULL para una interfaz. Para seleccionar una aplicación de servidor proporcionada por EPV, pase la dirección de un EPV cuyo valor ha sido declarado por el servidor como el valor de MgrEpv de un parámetro. Un valor distinto de null para mgrEpv un parámetro siempre invalida un EPV predeterminado en el código auxiliar del servidor.

El compilador MIDL genera automáticamente un tipo de datos EPV de administrador (RPC_MGR_EPV) para que una aplicación de servidor la use en la construcción de EPV de administrador. Un administrador EPV debe contener exactamente un punto de entrada (dirección de función) para cada procedimiento definido en el archivo IDL.

Un servidor debe proporcionar un EPV que no sea NULL en los casos siguientes:

  • Cuando los nombres de las rutinas de administrador difieren de los nombres de procedimiento declarados en la definición de interfaz
  • Cuando el servidor usa el EPV predeterminado para registrar otra implementación de la interfaz

Un servidor declara un administrador EPV inicializando una variable de tipo if-name**_SERVER_EPV** para cada implementación de la interfaz.

Registrar una sola implementación de una interfaz

Cuando un servidor ofrece solo una implementación de una interfaz, el servidor llama a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 solo una vez. En el caso estándar, el servidor usa el administrador predeterminado EPV. (La excepción es cuando el administrador usa nombres de rutina que difieren de los declarados en la interfaz).

En el caso estándar, se proporcionan los siguientes valores para las llamadas a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2:

  • EPV de administrador

    Para usar el valor predeterminado de EPV, especifique un valor NULL para el mgrEpv de un parámetro.

  • UUID de tipo de administrador

    Al usar el EPV predeterminado, registre la interfaz con un UUID de tipo de administrador nulo proporcionando un valor null o un UUID nulo para el parámetro MgrTypeUuid . En este caso, todas las llamadas a procedimientos remotos, independientemente del UUID de objeto en su identificador de enlace, se envían al EPV predeterminado, suponiendo que no se han realizado llamadas RpcObjectSetType .

    También puede proporcionar un UUID de tipo administrador no nulo. En este caso, también debe llamar a la rutina RpcObjectSetType .

Registrar varias implementaciones de una interfaz

Puede proporcionar más de una implementación de los procedimientos remotos especificados en el archivo IDL. La aplicación de servidor llama a RpcObjectSetType para asignar UUID de objeto a los UUID de tipo y llama a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 para asociar EPVs de administrador con un tipo UUID. Cuando llega una llamada a procedimiento remoto con su UUID de objeto, la biblioteca en tiempo de ejecución del servidor RPC asigna el UUID de objeto a un UUID de tipo. A continuación, la aplicación de servidor usa el tipo UUID y el UUID de interfaz para seleccionar el administrador EPV.

También puede especificar su propia función para resolver la asignación del UUID del objeto al tipo de administrador UUID. La función de asignación se especifica al llamar a RpcObjectSetInqFn.

Para ofrecer varias implementaciones de una interfaz, un servidor debe registrar cada implementación llamando a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 por separado. Para cada implementación, un servidor registra, proporciona el mismo parámetro IfSpec , pero un par diferente de MgrTypeUuid y MgrEpv a parámetros.

En el caso de varios administradores, use RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 de la siguiente manera:

  • EPV de administrador

    Para ofrecer varias implementaciones de una interfaz, un servidor debe:

    Tenga en cuenta que el servidor también puede registrarse con el administrador predeterminado EPV.

  • UUID de tipo de administrador

    Proporcione un UUID de tipo de administrador para cada EPV de la interfaz. El UUID de tipo nulo (o valor null ) para mgrTypeUuid se puede especificar un parámetro para uno de los EPV de administrador. Cada UUID de tipo debe ser diferente.

Reglas para invocar rutinas del administrador

La biblioteca en tiempo de ejecución rpc envía una llamada de procedimiento remoto entrante a un administrador que ofrece la interfaz RPC solicitada. Cuando se registran varios administradores para una interfaz, la biblioteca en tiempo de ejecución rpc debe seleccionar una de ellas. Para seleccionar un administrador, la biblioteca en tiempo de ejecución rpc usa el UUID de objeto especificado por el identificador de enlace de la llamada.

La biblioteca en tiempo de ejecución aplica las siguientes reglas al interpretar el UUID de objeto de una llamada a procedimiento remoto:

  • UUID de objeto nulos

    A un UUID de objeto nulo se le asigna automáticamente el UUID de tipo nulo (no es válido especificar un UUID de objeto nulo en la rutina RpcObjectSetType ). Por lo tanto, una llamada a procedimiento remoto cuyo identificador de enlace contiene un UUID de objeto nulo se envía automáticamente al administrador registrado con el UUID de tipo nulo, si existe.

  • UUID de objeto no nulos

    En principio, una llamada a procedimiento remoto cuyo identificador de enlace contiene un UUID de objeto no nulo debe ser procesado por un administrador cuyo tipo UUID coincide con el tipo del UUID de objeto. Sin embargo, la identificación del administrador correcto requiere que el servidor haya especificado el tipo de ese UUID de objeto llamando a la rutina RpcObjectSetType .

    Si un servidor no puede llamar a la rutina RpcObjectSetType para un UUID de objeto no nulo, una llamada de procedimiento remoto para ese UUID de objeto va al administrador EPV que servicios llama a procedimiento remoto con un UUID de objeto nulo (es decir, el UUID de tipo nulo).

    Las llamadas a procedimiento remoto con un UUID de objeto no nulo en el identificador de enlace no se pueden ejecutar si el servidor asignó ese UUID de objeto no nulo un UUID de tipo llamando a la rutina RpcObjectSetType, pero tampoco registró un EPV de administrador para ese tipo UUID llamando a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2.

En la tabla siguiente se resumen las acciones que usa la biblioteca en tiempo de ejecución para seleccionar la rutina de administrador.

UUID de objeto de llamada ¿Tipo de conjunto de servidores para el UUID de objeto? ¿Tipo de EPV registrado en el servidor? Acción de distribución
Nula No aplicable Usa el administrador con el UUID de tipo nulo.
Nula No es aplicable No Error (RPC_S_UNSUPPORTED_TYPE); rechaza la llamada a procedimiento remoto.
No nulo Usa el administrador con el mismo UUID de tipo.
No nulo No Omitido Usa el administrador con el UUID de tipo nulo. Si no hay ningún administrador con el UUID de tipo nulo, error (RPC_S_UNSUPPORTEDTYPE); rechaza la llamada a procedimiento remoto.
No nulo No Error (RPC_S_UNSUPPORTEDTYPE); rechaza la llamada a procedimiento remoto.

 

El UUID de objeto de la llamada es el UUID de objeto que se encuentra en un identificador de enlace para una llamada a procedimiento remoto.

El servidor establece el tipo del UUID de objeto llamando a RpcObjectSetType para especificar el tipo UUID de un objeto.

El servidor registra el tipo para el administrador EPV mediante una llamada a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 con el mismo uuID de tipo.

Nota

El UUID de objeto nulo siempre se asigna automáticamente al UUID de tipo nulo. No es válido especificar un UUID de objeto nulo en la rutina RpcObjectSetType .

 

Envío de una llamada a procedimiento remoto a una rutina de administrador del servidor

En las tablas siguientes se muestran los pasos que tarda la biblioteca en tiempo de ejecución de RPC para enviar una llamada a procedimiento remoto a una rutina de administrador de servidores.

En las tablas siguientes se describe un caso sencillo en el que el servidor registra el administrador predeterminado EPV.

Tabla del Registro de interfaz

UUID de interfaz UUID de tipo de administrador Vector de punto de entrada
uuid1 Nula EPV predeterminado

 

Tabla del Registro de objetos

UUID de objeto Tipo de objeto
Nula Nula
(Cualquier otro UUID de objeto) Nula

 

Asignación del identificador de enlace a un vector de punto de entrada (EPV)

UUID de interfaz (desde el identificador de enlace de cliente) UUID de objeto (desde el identificador de enlace de cliente) Tipo de objeto (de la tabla del Registro de objetos) Administrador EPV (de la tabla del Registro de interfaz)
uuid1 Nula Nula EPV predeterminado
Lo mismo que antes. uuidA Nula EPV predeterminado

 

En los pasos siguientes se describen las acciones que realiza la biblioteca en tiempo de ejecución del servidor RPC, como se muestra en las tablas anteriores, cuando un cliente con UUID de interfaz uuid1 lo llama.

  1. El servidor llama a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 para asociar una interfaz que ofrece con el UUID de tipo de administrador nulo y con el administrador predeterminado generado por MIDL EPV. Esta llamada agrega una entrada en la tabla del Registro de interfaz. El UUID de interfaz se encuentra en ifspec un parámetro .

  2. De forma predeterminada, la tabla del Registro de objetos asocia todos los UUID de objeto con el UUID de tipo nulo. En este ejemplo, el servidor no llama a RpcObjectSetType.

  3. La biblioteca en tiempo de ejecución del servidor recibe un código de procedimiento remoto que contiene el UUID de interfaz al que pertenece la llamada y el UUID de objeto del identificador de enlace de la llamada.

    Consulte las siguientes entradas de referencia de función para ver cómo se establece un UUID de objeto en un identificador de enlace:

  4. Con el UUID de interfaz de la llamada a procedimiento remoto, la biblioteca en tiempo de ejecución del servidor busca ese UUID de interfaz en la tabla del Registro de interfaz.

    Si el servidor no registró la interfaz mediante RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2, la llamada al procedimiento remoto vuelve al autor de la llamada con un código de estado de RPC_S_UNKNOWN_IF.

  5. Con el UUID de objeto del identificador de enlace, la biblioteca en tiempo de ejecución del servidor busca ese UUID de objeto en la tabla del Registro de objetos. En este ejemplo, todos los UUID de objeto se asignan al tipo de objeto nulo.

  6. La biblioteca en tiempo de ejecución del servidor localiza el tipo de administrador nulo en la tabla del Registro de interfaz.

  7. La combinación del UUID de interfaz y el tipo nulo en la tabla del Registro de interfaz se resuelve en el EPV predeterminado, que contiene las rutinas del administrador del servidor que se van a ejecutar para el UUID de interfaz que se encuentra en la llamada a procedimiento remoto.

Supongamos que el servidor ofrece varias interfaces y varias implementaciones de cada interfaz, como se describe en las tablas siguientes.

Tabla del Registro de interfaz

UUID de interfaz UUID de tipo administrador Vector de punto de entrada
uuid1 Nula epv1
uuid1 uuid3 epv4
uuid2 uuid4 epv2
uuid2 uuid7 epv3

 

Tabla del Registro de objetos

UUID de objeto Tipo de objeto
uuidA uuid3
uuidB uuid7
uuidC uuid7
uuidD uuid3
uuidE uuid3
uuidF uuid8
Nula Nula
(Cualquier otro UUID) Nula

 

Asignación del identificador de enlace a un vector de punto de entrada

UUID de interfaz (desde el identificador de enlace de cliente) UUID de objeto (desde el identificador de enlace de cliente) Tipo de objeto (de la tabla del Registro de objetos) EPV del administrador (desde la tabla del Registro de interfaz)
uuid1 Nula Nula epv1
uuid1 uuidA uuid3 epv4
uuid1 uuidD uuid3 epv4
uuid1 uuidE uuid3 epv4
uuid2 uuidB uuid7 epv3
uuid2 uuidC uuid7 epv3

 

En los pasos siguientes se describen las acciones que lleva a cabo la biblioteca en tiempo de ejecución del servidor, como se muestra en las tablas anteriores cuando un cliente con UUID de interfaz uuid2 y el UUID de objeto lo llama.

  1. El servidor llama a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 para asociar las interfaces que ofrece con los diferentes EPV de administrador. Las entradas de la tabla del Registro de interfaz reflejan cuatro llamadas de RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 para ofrecer dos interfaces, con dos implementaciones (EPV) para cada interfaz.

  2. El servidor llama a RpcObjectSetType para establecer el tipo de cada objeto que ofrece. Además de la asociación predeterminada del objeto nulo a un tipo nulo, todos los demás UUID de objeto no se encuentran explícitamente en la tabla del Registro de objetos también se asignan al UUID de tipo nulo.

    En este ejemplo, el servidor llama a la rutina RpcObjectSetType seis veces.

  3. La biblioteca en tiempo de ejecución del servidor recibe una llamada a procedimiento remoto que contiene el UUID de interfaz al que pertenece la llamada y un UUID de objeto del identificador de enlace de la llamada.

  4. Con el UUID de interfaz desde la llamada a procedimiento remoto, la biblioteca en tiempo de ejecución del servidor localiza el UUID de interfaz en la tabla del Registro de interfaz.

  5. Con el UUID de objeto uuidC del identificador de enlace, la biblioteca en tiempo de ejecución del servidor busca el UUID de objeto en la tabla del Registro de objetos y encuentra que se asigna al tipo uuid7.

  6. Para buscar el tipo de administrador, la biblioteca en tiempo de ejecución del servidor combina el UUID de interfaz, uuid2 y escribe uuid7 en la tabla del Registro de interfaz. Esto se resuelve en epv3, que contiene la rutina del administrador del servidor que se va a ejecutar para la llamada a procedimiento remoto.

Las rutinas de epv2 nunca se ejecutarán porque el servidor no ha llamado a la rutina RpcObjectSetType para agregar objetos con un UUID de tipo uuid4 a la tabla del Registro de objetos.

Una llamada a procedimiento remoto con uuid2 de interfaz y uuid de objeto UUID uuidF vuelve al autor de la llamada con un código de estado de RPC_S_UNKNOWN_MGR_TYPE porque el servidor no llamó a RpcServerRegisterIf, RpcServerRegisterIfEx o RpcServerRegisterIf2 para registrar la interfaz con un tipo de administrador de uuid8.

Valores devueltos

Esta función devuelve uno de los valores siguientes.

Value Significado
RPC_S_OK Correcto
RPC_S_TYPE_ALREADY_REGISTERED Tipo UUID ya registrado

 

Proporcionar su propia función de consulta de objetos

Considere un servidor que administra miles de objetos de muchos tipos diferentes. Cada vez que se inicia el servidor, la aplicación de servidor tendría que llamar a la función RpcObjectSetType para cada uno de los objetos, aunque los clientes podrían hacer referencia solo a algunos de ellos (o tardar mucho tiempo en hacer referencia a ellos). Es probable que estos miles de objetos estén en el disco, por lo que recuperar sus tipos consumiría mucho tiempo. Además, la tabla interna que asigna el UUID de objeto al UUID del tipo de administrador duplicaría esencialmente la asignación mantenida con los propios objetos.

Para mayor comodidad, el conjunto de funciones RPC incluye la función RpcObjectSetInqFn. Con esta función, se proporciona su propia función de consulta de objetos.

Por ejemplo, puede proporcionar su propia función de consulta de objetos al asignar objetos 100–199 al número 1, 200–299 para escribir el número 2, etc. La función de consulta de objetos también se puede extender a un sistema de archivos distribuido, donde la aplicación de servidor no tiene una lista de todos los archivos (UUID de objeto) disponibles, o cuando los UUID de objeto del sistema de archivos y no desea cargar previamente todas las asignaciones entre UUID de objeto y UUID de tipo.

RpcBindingFromStringBinding

RpcBindingSetObject

RpcNsBindingExport

RpcNsBindingImportBegin

RpcNsBindingLookupBegin

RpcObjectSetType

RpcServerRegisterIf

RpcServerRegisterIf2

RpcServerRegisterIfEx

RpcServerUnregisterIf

RpcServerUnregisterIfEx