Interfaz IMarshal (objidl.h)

Permite a un objeto COM para definir y administrar el cálculo de referencias de los punteros de la interfaz.

Herencia

La interfaz IMarshal hereda de la interfaz IUnknown . IMarshal también tiene estos tipos de miembros:

Métodos

La interfaz IMarshal tiene estos métodos.

 
IMarshal::D isconnectObject

El método IMarshal::D isconnectObject (objidl.h) libera todas las conexiones a un objeto antes de apagarse.
IMarshal::GetMarshalSizeMax

Recupera el tamaño máximo del búfer que se necesitará durante la serialización.
IMarshal::GetUnmarshalClass

Recupera el CLSID del código de desmarización.
IMarshal::MarshalInterface

El método IMarshal::MarshalInterface (objidl.h) serializa un puntero de interfaz.
IMarshal::ReleaseMarshalData

El método IMarshal::ReleaseMarshalData (objidl.h) destruye un paquete de datos serializado.
IMarshal::UnmarshalInterface

El método IMarshal::UnmarshalInterface (objidl.h) desmarshala un puntero de interfaz.

Comentarios

La serialización es el proceso de empaquetar datos en paquetes para la transmisión a un proceso o equipo diferente. La desmarshaling es el proceso de recuperación de esos datos al final receptor. En cualquier llamada dada, los argumentos de método se serializarán y desmarcalizarán en una dirección, mientras que los valores devueltos se serializarán y desmarizarán en la otra.

Aunque la serialización se aplica a todos los tipos de datos, los punteros de interfaz requieren un control especial. El problema fundamental es cómo el código de cliente que se ejecuta en un espacio de direcciones puede desreferenciar correctamente un puntero a una interfaz de un objeto que reside en un espacio de direcciones diferente. La solución COM es para que una aplicación cliente se comunique con el objeto original a través de un objeto suplente o proxy, que reside en el proceso del cliente. El proxy contiene una referencia a una interfaz en el objeto original y entrega al cliente un puntero a una interfaz en sí misma. Cuando el cliente llama a un método de interfaz en el objeto original, su llamada va realmente al proxy. Por lo tanto, desde el punto de vista del cliente, todas las llamadas están en proceso.

Al recibir una llamada, el proxy serializa los argumentos del método y a través de algún medio de comunicación entre procesos, como RPC, los pasa al código en el proceso del servidor, que anula las referencias de los argumentos y los pasa al objeto original. Este mismo código serializa los valores devueltos para la transmisión al proxy, que desmariza los valores y los pasa a la aplicación cliente.

IMarshal proporciona métodos para crear, inicializar y administrar un proxy en un proceso de cliente; no determina cómo debe comunicarse el proxy con el objeto original. La implementación predeterminada COM de IMarshal usa RPC. Al implementar esta interfaz usted mismo, tiene la libertad de elegir cualquier método de comunicación entre procesos que considere adecuado para la aplicación( memoria compartida, canalización con nombre, identificador de ventana, RPC, en resumen, lo que sea que funcione.

Implementación predeterminada de IMarshal

COM usa su propia implementación interna de la interfaz IMarshal para serializar cualquier objeto que no proporcione su propia implementación. COM realiza esta determinación consultando el objeto para IMarshal. Si falta la interfaz, COM tiene como valor predeterminado su implementación interna.

La implementación predeterminada COM de IMarshal usa un proxy genérico para cada objeto y crea códigos auxiliares individuales y servidores proxy, según sean necesarios, para cada interfaz implementada en el objeto. Este mecanismo es necesario porque COM no puede saber de antemano qué interfaces concretas puede implementar un objeto determinado. Los desarrolladores que no usan serializaciones predeterminadas COM, optando por escribir sus propias rutinas de proxy y serialización, saben en tiempo de compilación todas las interfaces que se van a encontrar en sus objetos y, por tanto, comprender exactamente qué código de serialización es necesario. COM, al proporcionar compatibilidad con la serialización de todos los objetos, debe hacerlo en tiempo de ejecución.

El proxy de interfaz reside en el proceso de cliente; el código auxiliar de interfaz reside en el servidor. Juntos, cada par controla todas las serializaciones de la interfaz. El trabajo de cada proxy de interfaz es serializar argumentos y valores devueltos desmarshal y parámetros que se pasan hacia atrás y hacia delante en llamadas posteriores a su interfaz. El trabajo de cada código auxiliar de interfaz es anular los argumentos de funciónmarshal y pasarlos al objeto original y, a continuación, serializar los valores devueltos y los parámetros de salida que devuelve el objeto.

Proxy y código auxiliar se comunican mediante un canal RPC (llamada a procedimiento remoto), que utiliza la infraestructura RPC del sistema para la comunicación entre procesos. El canal RPC implementa una única interfaz, IRpcChannelBuffer, a la que los servidores proxy de interfaz y los códigos auxiliares contienen un puntero. El proxy y el código auxiliar llaman a la interfaz para obtener un paquete de serialización, enviar los datos a su homólogo y destruir el paquete cuando se realizan. El código auxiliar de la interfaz también contiene un puntero al objeto original.

Para cualquier interfaz determinada, el proxy y el código auxiliar se implementan como instancias de la misma clase, que se enumeran para cada interfaz del registro del sistema en la etiqueta ProxyStubClsid32. Esta entrada asigna el IID de la interfaz al CLSID de sus objetos proxy y de código auxiliar. Cuando COM necesita serializar una interfaz, busca en el registro del sistema para obtener el CLSID adecuado. El servidor identificado por este CLSID implementa tanto el proxy de interfaz como el código auxiliar de interfaz.

La mayoría de las veces, la clase a la que hace referencia este CLSID se genera automáticamente mediante una herramienta cuya entrada es una descripción de las firmas de función y la semántica de una interfaz determinada, escrita en algún lenguaje de descripción de interfaz. Aunque el uso de este lenguaje es muy recomendable y se recomienda por motivos de precisión, no es necesario hacerlo. Los proxies y los códigos auxiliares son simplemente componentes COM utilizados por la infraestructura RPC y, como tal, se pueden escribir de cualquier manera deseada, siempre y cuando se retendrán los contratos externos correctos. El programador que diseña una nueva interfaz es responsable de garantizar que todos los servidores proxy de interfaz y códigos auxiliares que existan estén de acuerdo en la representación de sus datos serializado.

Cuando se crean, los servidores proxy de interfaz siempre se agregan en un proxy mayor, que representa el objeto en su conjunto. Este proxy de objeto también agrega el objeto proxy genérico COM, que se conoce como administrador de proxy. El administrador de proxy implementa dos interfaces: IUnknown e IMarshal. Todas las demás interfaces que se pueden implementar en un objeto se exponen en su proxy de objeto a través de la agregación de servidores proxy de interfaz individuales. Un cliente que contiene un puntero al proxy de objeto "cree" que contiene un puntero al objeto real.

Un proxy que representa el objeto en su conjunto es necesario en el proceso de cliente para que un cliente pueda distinguir las llamadas a las mismas interfaces implementadas en objetos completamente diferentes. Sin embargo, este requisito no existe en el proceso de servidor, donde reside el propio objeto, porque todos los códigos auxiliares de interfaz se comunican solo con los objetos para los que se crearon. No es posible ninguna otra conexión.

Los códigos auxiliares de interfaz, a diferencia de los servidores proxy de interfaz, no se agregan porque no es necesario que parezcan que algún cliente externo forme parte de un conjunto mayor. Cuando se conecta, un código auxiliar de interfaz recibe un puntero al objeto de servidor al que debe reenviar las invocaciones de método que recibe. Aunque resulta útil hacer referencia conceptualmente a un administrador de código auxiliar, lo que significa cualquier parte del código y estado de la infraestructura RPC del lado servidor que preste servicio a la comunicación remota de un objeto determinado, no hay ningún requisito directo de que el código y el estado tomen cualquier forma concreta y bien especificada.

La primera vez que un cliente solicita un puntero a una interfaz en un objeto determinado, COM carga un código auxiliar IClassFactory en el proceso del servidor y lo usa para serializar el primer puntero de vuelta al cliente. En el proceso de cliente, COM carga el proxy genérico para el objeto de generador de clases y llama a su implementación de IMarshal para desmarshalar ese primer puntero. COM crea el primer proxy de interfaz y lo entrega un puntero al canal RPC. Por último, COM devuelve el puntero IClassFactory al cliente, que lo usa para llamar a IClassFactory::CreateInstance, pasando una referencia a la interfaz.

De nuevo en el proceso del servidor, COM ahora crea una nueva instancia del objeto, junto con un código auxiliar para la interfaz solicitada. Este código auxiliar serializa el puntero de interfaz de nuevo al proceso de cliente, donde se crea otro proxy de objeto, esta vez para el propio objeto. También se crea un proxy para la interfaz solicitada, un puntero al que se devuelve al cliente. Con las llamadas posteriores a otras interfaces del objeto, COM cargará los códigos auxiliares de interfaz y los servidores proxy adecuados según sea necesario.

Cuando se crea un nuevo proxy de interfaz, COM le entrega un puntero a la implementación del administrador de proxy de IUnknown, a la que delega todas las llamadas queryInterface . Cada proxy de interfaz implementa dos interfaces propias: la interfaz que representa e IRpcProxyBuffer. El proxy de interfaz expone su propia interfaz directamente a los clientes, que pueden obtener su puntero llamando a QueryInterface en el administrador de proxy. Sin embargo, solo COM puede llamar a IRpcProxyBuffer, que se usa para conectar y desconectar el proxy al canal RPC. Un cliente no puede consultar un proxy de interfaz para obtener un puntero a la interfaz IRpcProxyBuffer .

En el lado servidor, cada código auxiliar de interfaz implementa IRpcStubBuffer. El código de servidor que actúa como administrador de código auxiliar llama a IRpcStubBuffer::Connect y pasa el código auxiliar de interfaz al puntero IUnknown de su objeto.

Cuando un proxy de interfaz recibe una invocación de método, obtiene un paquete de serialización de su canal RPC a través de una llamada a IRpcChannelBuffer::GetBuffer. El proceso de serialización de los argumentos copiará los datos en el búfer. Cuando se completa la serialización, el proxy de interfaz invoca IRpcChannelBuffer::SendReceive para enviar el paquete serializado al código auxiliar de interfaz correspondiente. Cuando se devuelve IRpcChannelBuffer::SendReceive , el búfer en el que se serializaron los argumentos se reemplazará por un nuevo búfer que contiene los valores devueltos serializado desde el código auxiliar de la interfaz. El proxy de interfaz desmarshala los valores devueltos, invoca IRpcChannelBuffer::FreeBuffer para liberar el búfer y, a continuación, devuelve los valores devueltos al autor de la llamada original del método.

Es la implementación de IRpcChannelBuffer::SendReceive que envía realmente la solicitud al proceso del servidor y que sabe cómo identificar el proceso del servidor y, dentro de ese proceso, el objeto al que se debe enviar la solicitud. La implementación del canal también sabe cómo reenviar la solicitud al administrador de código auxiliar adecuado en ese proceso. El código auxiliar de interfaz desmarshala los argumentos del búfer proporcionado, invoca el método indicado en el objeto de servidor y serializa los valores devueltos en un nuevo búfer asignado por una llamada a IRpcChannelBuffer::GetBuffer. A continuación, el canal transmite el paquete de datos devuelto al proxy de interfaz, que todavía está en medio de IRpcChannelBuffer::SendReceive, que vuelve al proxy de interfaz.

Se puede usar una instancia determinada de un proxy de interfaz para atender más de una interfaz, siempre y cuando se cumplan las condiciones siguientes:

  • Los IID de las interfaces afectadas deben asignarse al proxyStubClsid adecuado en el registro del sistema.
  • El proxy de interfaz debe admitir llamadas a QueryInterface desde una interfaz admitida a las demás interfaces, como de costumbre, así como desde IUnknown e IRpcProxyBuffer.
Una sola instancia de un código auxiliar de interfaz también puede atender más de una interfaz, pero solo si ese conjunto de interfaces tiene una relación estricta de herencia única. Esta restricción existe porque el código auxiliar puede dirigir las invocaciones de método a varias interfaces solo donde conoce de antemano qué métodos se implementan en qué interfaces.

En varios momentos, los servidores proxy y los códigos auxiliares tendrán que asignar o liberar memoria. Por ejemplo, los servidores proxy de interfaz deberán asignar memoria en la que devolver parámetros a su llamador. En este sentido, los servidores proxy de interfaz y los códigos auxiliares de interfaz son simplemente componentes COM normales, en que deben usar el asignador de tareas estándar. (Consulte CoGetMalloc).

Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000 Professional [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows 2000 Server [aplicaciones de escritorio | Aplicaciones para UWP]
Plataforma de destino Windows
Encabezado objidl.h (incluir ObjIdl.h)

Consulte también

IStdMarshalInfo