Detalhes do marshaling
Se você usar marshaling padrão, COM lida com todos os detalhes descritos aqui para você. No entanto, existem aqueles poucos programadores que precisam desses detalhes e para aqueles interessados nas informações subjacentes. Marshaling é o processo de empacotar e desempacotar parâmetros para que uma chamada de procedimento remoto possa ocorrer.
Diferentes tipos de parâmetros são agrupados de maneiras diferentes. Por exemplo, marshaling um parâmetro inteiro envolve simplesmente copiar o valor para o buffer de mensagens. (Embora mesmo neste caso simples, há problemas como a ordem de bytes para lidar em chamadas entre computadores.) Empacotar uma matriz, no entanto, é um processo mais complexo. Os membros da matriz são copiados em uma ordem específica para que o outro lado possa reconstruir a matriz exatamente. Quando um ponteiro é empacotado, os dados para os quais o ponteiro está apontando são copiados seguindo regras e convenções para lidar com ponteiros aninhados em estruturas. Existem funções exclusivas para lidar com o empacotamento de cada tipo de parâmetro.
Com o marshaling padrão, os proxies e stubs são recursos de todo o sistema para a interface e interagem com o canal por meio de um protocolo padrão. O empacotamento padrão pode ser usado tanto por interfaces padrão definidas por COM quanto por interfaces personalizadas, da seguinte maneira:
- No caso da maioria das interfaces COM, os proxies e stubs para empacotamento padrão são objetos de componente em processo que são carregados a partir de uma DLL de todo o sistema fornecida pelo COM em Ole32.dll.
- No caso de interfaces personalizadas, os proxies e stubs para empacotamento padrão são gerados pelo designer de interface, normalmente com MIDL. Esses proxies e stubs são configurados estaticamente no Registro, para que qualquer cliente em potencial possa usar a interface personalizada além dos limites do processo. Esses proxies e stubs são carregados de uma DLL localizada por meio do registro do sistema, usando o ID da interface (IID) para a interface personalizada que eles marshal.
- Uma alternativa ao uso do MIDL para gerar proxies e stubs para interfaces personalizadas, uma biblioteca de tipos pode ser gerada em vez disso e o mecanismo de empacotamento controlado por biblioteca de tipos fornecido pelo sistema irá organizar a interface.
Como alternativa ao marshaling padrão, uma interface (padrão ou personalizada) pode usar o marshaling personalizado. Com o empacotamento personalizado, um objeto implementa dinamicamente os proxies em tempo de execução para cada interface suportada. Para qualquer interface específica, o objeto pode selecionar marshaling padrão fornecido por COM ou empacotamento personalizado. Essa escolha é feita pelo objeto em uma base de interface por interface. Uma vez que a escolha é feita para uma determinada interface, ela permanece em vigor durante a vida útil do objeto. No entanto, uma interface em um objeto pode usar empacotamento personalizado, enquanto outra usa empacotamento padrão.
O empacotamento personalizado é inerentemente exclusivo do objeto que o implementa. Ele usa proxies implementados pelo objeto e fornecidos ao sistema a pedido em tempo de execução. Os objetos que implementam o empacotamento personalizado devem implementar a interface IMarshal, enquanto os objetos que oferecem suporte ao empacotamento padrão não.
Se você decidir escrever uma interface personalizada, deverá fornecer suporte de empacotamento para ela. Normalmente, você fornecerá uma DLL de empacotamento padrão para a interface que você projetar. Você pode criar o código proxy/stub e a DLL proxy/stub ou pode criar uma biblioteca de tipos que o COM usará para fazer empacotamento controlado por dados (usando os dados na biblioteca de tipos).
Para um cliente fazer uma chamada para um método de interface em um objeto em outro processo envolve a cooperação de vários componentes. O proxy padrão é uma parte do código específico da interface que reside no espaço de processo do cliente e prepara os parâmetros da interface para transmissão. Embala-os, ou marshals, de tal forma que possam ser recriados e compreendidos no processo de recebimento. O stub padrão, também um pedaço de código específico da interface, reside no espaço de processo do servidor e reverte o trabalho do proxy. O stub desempacota, ou desempacota, os parâmetros enviados e os encaminha para o aplicativo objeto. Ele também empacota informações de resposta para enviar de volta ao cliente.
Observação
Leitores mais familiarizados com RPC do que COM podem estar acostumados a ver os termos stub de cliente e stub de servidor. Esses termos são análogos a proxy e stub.
Componentes das comunicações entre processos
O diagrama a seguir mostra o fluxo de comunicação entre os componentes envolvidos. No lado do cliente do limite do processo, a chamada de método do cliente passa pelo proxy e, em seguida, para o canal, que faz parte da biblioteca COM. O canal envia o buffer que contém os parâmetros empacotados para a biblioteca de tempo de execução RPC, que o transmite através do limite do processo. O tempo de execução RPC e as bibliotecas COM existem em ambos os lados do processo. A distinção entre o canal e o tempo de execução RPC é uma característica dessa implementação e não faz parte do modelo de programação ou do modelo conceitual para objetos cliente/servidor COM. Os servidores COM veem apenas o proxy ou stub e, indiretamente, o canal. Implementações futuras podem usar diferentes camadas abaixo do canal ou nenhuma camada.
Tópicos relacionados