Partilhar via


Comunicação Inter-Object

O COM foi projetado para permitir que os clientes se comuniquem de forma transparente com objetos, independentemente de onde esses objetos estão sendo executados — no mesmo processo, no mesmo computador ou em um computador diferente. Isso fornece um único modelo de programação para todos os tipos de objetos e para clientes de objetos e servidores de objetos.

Do ponto de vista de um cliente, todos os objetos são acessados através de ponteiros de interface. Um ponteiro deve estar em processo. Na verdade, qualquer chamada para uma função de interface sempre atinge algum pedaço de código em processo primeiro. Se o objeto estiver em processo, a chamada o alcançará diretamente, sem nenhum código de infraestrutura do sistema interveniente. Se o objeto estiver fora do processo, a chamada primeiro alcançará o que é chamado de objeto "proxy" fornecido pelo COM ou pelo objeto (se o implementador desejar). Os pacotes de proxy chamam parâmetros (incluindo quaisquer ponteiros de interface) e geram a chamada de procedimento remoto apropriada (ou outro mecanismo de comunicação no caso de proxies gerados de forma personalizada) para o outro processo ou para o outro computador onde a implementação do objeto está localizada. Este processo de empacotamento de ponteiros para transmissão através dos limites do processo é chamado marshaling.

Do ponto de vista de um servidor, todas as chamadas para as funções de interface de um objeto são feitas através de um ponteiro para essa interface. Novamente, um ponteiro tem contexto apenas em um único processo, e o chamador deve sempre ser algum pedaço de código em processo. Se o objeto estiver em processo, o chamador será o próprio cliente. Caso contrário, o chamador é um objeto "stub" fornecido pelo COM ou pelo próprio objeto. O stub recebe a chamada de procedimento remoto (ou outro mecanismo de comunicação no caso de proxies gerados de forma personalizada) do "proxy" no processo do cliente, desmarechal os parâmetros e chama a interface apropriada no objeto do servidor. Do ponto de vista de clientes e servidores, eles sempre se comunicam diretamente com algum outro código em processo.

A COM fornece uma implementação de marshaling, referida como marshaling padrão. Esta implementação funciona muito bem para a maioria dos objetos e reduz consideravelmente os requisitos de programação, tornando o processo de empacotamento efetivamente transparente.

A separação clara entre interface e implementação da transparência do processo da COM pode, no entanto, atrapalhar em algumas situações. O design de uma interface que se concentra em sua função do ponto de vista do cliente pode, às vezes, levar a decisões de design que entram em conflito com a implementação eficiente dessa interface em uma rede. Em casos como este, o que é necessário não é pura transparência do processo, mas "transparência do processo, a menos que você precise se importar". O COM fornece esse recurso permitindo que um implementador de objetos ofereça suporte a de empacotamento personalizado (também chamado de IMarshal marshaling). O marshaling padrão é, de fato, um exemplo de marshaling personalizado; É a implementação padrão usada quando um objeto não requer marshaling personalizado.

Você pode implementar o marshaling personalizado para permitir que um objeto execute ações diferentes quando usado em uma rede do que ele leva sob acesso local e é completamente transparente para o cliente. Essa arquitetura torna possível projetar interfaces cliente/objeto sem levar em conta os problemas de desempenho da rede e, posteriormente, resolver problemas de desempenho da rede sem interromper o design estabelecido.

A COM não especifica como os componentes são estruturados; especifica como interagem. COM deixa a preocupação com a estrutura interna de um componente para linguagens de programação e ambientes de desenvolvimento. Por outro lado, os ambientes de programação não têm padrões definidos para trabalhar com objetos fora do aplicativo imediato. O Microsoft Visual C++, por exemplo, funciona muito bem para manipular objetos dentro de um aplicativo, mas não tem suporte para trabalhar com objetos fora do aplicativo. Geralmente, todas as outras linguagens de programação são as mesmas a este respeito. Portanto, para fornecer interoperabilidade em toda a rede, COM, através de interfaces independentes de linguagem, pega onde as linguagens de programação param.

A dupla indireção da estrutura vtbl significa que os ponteiros na tabela de ponteiros de função não precisam apontar diretamente para a implementação real no objeto real. Este é o cerne da transparência dos processos.

Para servidores em processo, onde o objeto é carregado diretamente no processo do cliente, os ponteiros de função na tabela apontam diretamente para a implementação real. Nesse caso, uma chamada de função do cliente para um método de interface transfere diretamente o controle de execução para o método. No entanto, isso não pode funcionar para objetos locais, muito menos remotos, porque os ponteiros para a memória não podem ser compartilhados entre processos. No entanto, o cliente deve ser capaz de chamar métodos de interface como se estivesse chamando a implementação real. Assim, o cliente transfere uniformemente o controle para um método em algum objeto, fazendo a chamada.

Um cliente sempre chama métodos de interface em algum objeto em processo. Se o objeto real for local ou remoto, a chamada será feita para um objeto proxy, que fará uma chamada de procedimento remoto para o objeto real.

Então, qual método é realmente executado? A resposta é que sempre que há uma chamada para uma interface fora do processo, cada método de interface é implementado por um objeto proxy. O objeto proxy é sempre um objeto em processo que atua em nome do objeto que está sendo chamado. Este objeto proxy sabe que o objeto real está sendo executado em um servidor local ou remoto.

O objeto proxy empacota os parâmetros de função em alguns pacotes de dados e gera uma chamada RPC para o objeto local ou remoto. Esse pacote é captado por um objeto stub no processo do servidor no computador local ou remoto, que descompacta os parâmetros e faz a chamada para a implementação real do método. Quando essa função retorna, o stub empacota todos os parâmetros de saída e o valor de retorno e o envia de volta para o proxy, que os descompacta e os retorna ao cliente original.

Assim, cliente e servidor sempre conversam entre si como se tudo estivesse em processo. Todas as chamadas do cliente e todas as chamadas para o servidor estão, em algum momento, em processo. Mas como a estrutura vtbl permite que algum agente, como COM, intercete todas as chamadas de função e todos os retornos de funções, esse agente pode redirecionar essas chamadas para uma chamada RPC conforme necessário. Embora as chamadas em processo sejam mais rápidas do que as chamadas fora do processo, as diferenças de processo são completamente transparentes para o cliente e o servidor.

Para obter mais informações, consulte os seguintes tópicos:

Clientes e Servidores COM

Interface Marshaling