Marshaling de Interoperabilidade

A interoperabilidade gerencia como os dados são passados em argumentos de método e valores de retorno entre memória gerenciada e não gerenciada durante chamadas. O marshalling de interoperabilidade é uma atividade em tempo de execução realizada pelo serviço de empacotamento do common language runtime.

A maioria dos tipos de dados tem representações comuns na memória gerenciada e não gerenciada. O marshaller de interoperabilidade lida com esses tipos para você. Outros tipos podem ser ambíguos ou não representados na memória gerenciada.

Um tipo ambíguo pode ter várias representações não gerenciadas que mapeiam para um único tipo gerenciado ou informações de tipo ausentes, como o tamanho de uma matriz. Para tipos ambíguos, o marshaller fornece uma representação padrão e representações alternativas onde existem várias representações. Você pode fornecer instruções explícitas ao marshaller sobre como é organizar um tipo ambíguo.

Modelos de invocação de plataforma e interoperabilidade COM

O common language runtime fornece dois mecanismos para interoperar com código não gerenciado:

  • Invocar plataforma, que permite que o código gerenciado chame funções exportadas de uma biblioteca não gerenciada.
  • Interoperabilidade COM, que permite que o código gerenciado interaja com objetos COM (Component Object Model) por meio de interfaces.

Tanto a plataforma invoca quanto a interoperabilidade COM usam o agrupamento de interoperabilidade para mover com precisão os argumentos do método entre chamador e destinatário e vice-versa, se necessário. Como mostra a ilustração a seguir, uma chamada de método de invocação de plataforma flui de código gerenciado para código não gerenciado e nunca o contrário, exceto quando funções de retorno de chamada estão envolvidas. Embora as chamadas de invocação de plataforma possam fluir apenas de código gerenciado para não gerenciado, os dados podem fluir em ambas as direções como parâmetros de entrada ou saída. As chamadas do método de interoperabilidade COM podem fluir em qualquer direção.

Platform invoke

No nível mais baixo, ambos os mecanismos utilizam o mesmo serviço de interoperabilidade; no entanto, certos tipos de dados são suportados exclusivamente pela interoperabilidade COM ou pela invocação da plataforma. Para obter detalhes, consulte Comportamento de empacotamento padrão.

Marshalling e Apartamentos COM

O marshaller de interoperabilidade controla os dados entre o heap do common language runtime e o heap não gerenciado. O marshalling ocorre sempre que o chamador e o destinatário não podem operar na mesma instância de dados. O operador de interoperabilidade permite que o chamador e o destinatário pareçam operar com os mesmos dados, mesmo que tenham a sua própria cópia dos dados.

A COM também tem um marshaller que controla os dados entre apartamentos COM ou diferentes processos COM. Ao ligar entre código gerenciado e não gerenciado dentro do mesmo apartamento COM, o marshaller de interoperabilidade é o único marshaller envolvido. Ao chamar entre código gerenciado e código não gerenciado em um apartamento COM diferente ou em um processo diferente, tanto o marshaller de interoperabilidade quanto o marshaller COM estão envolvidos.

Clientes COM e Servidores Geridos

Um servidor gerenciado exportado com uma biblioteca de tipos registrada pelo Regasm.exe (Assembly Registration Tool) tem uma ThreadingModel entrada do Registro definida como Both. Esse valor indica que o servidor pode ser ativado em um apartamento single-threaded (STA) ou um apartamento multithreaded (MTA). O objeto de servidor é criado no mesmo apartamento que seu chamador, conforme mostrado na tabela a seguir:

Cliente COM Servidor .NET Requisitos de marshaling
STA Both torna-se STA. Agrupamento do mesmo apartamento.
MTA Both torna-se MTA. Agrupamento do mesmo apartamento.

Como o cliente e o servidor estão no mesmo apartamento, o serviço de interoperabilidade organiza automaticamente todos os dados. A ilustração a seguir mostra o serviço de interoperabilidade operando entre pilhas gerenciadas e não gerenciadas dentro do mesmo apartamento no estilo COM.

Interop marshalling between managed and unmanaged heaps

Se você planeja exportar um servidor gerenciado, esteja ciente de que o cliente COM determina o apartamento do servidor. Um servidor gerenciado chamado por um cliente COM inicializado em um MTA deve garantir a segurança do thread.

Clientes Gerenciados e Servidores COM

A configuração padrão para apartamentos de cliente gerenciados é MTA; no entanto, o tipo de aplicativo do cliente .NET pode alterar a configuração padrão. Por exemplo, uma configuração de apartamento de cliente do Visual Basic é STA. Você pode usar o System.STAThreadAttribute, o System.MTAThreadAttribute, a Thread.ApartmentState propriedade ou a Page.AspCompatMode propriedade para examinar e alterar a configuração do apartamento de um cliente gerenciado.

O autor do componente define a afinidade de thread de um servidor COM. A tabela a seguir mostra as combinações de configurações de apartamento para clientes .NET e servidores COM. Mostra também os requisitos de agrupamento resultantes para as combinações.

Cliente .NET Servidor COM Requisitos de marshaling
MTA (padrão) MTA

STA
Agrupamento de interoperabilidade.

Interoperabilidade e organização COM.
STA MTA

STA
Interoperabilidade e organização COM.

Agrupamento de interoperabilidade.

Quando um cliente gerenciado e um servidor não gerenciado estão no mesmo apartamento, o serviço de interoperabilidade organiza todos os dados. No entanto, quando cliente e servidor são inicializados em apartamentos diferentes, o empacotamento COM também é necessário. A ilustração a seguir mostra os elementos de uma chamada entre apartamentos:

Cross-apartment call between a .NET client and COM object

Para o agrupamento de apartamentos, você pode fazer o seguinte:

  • Aceite a sobrecarga do marshaling de apartamento cruzado, que é percetível apenas quando há muitas chamadas através do limite. Você deve registrar a biblioteca de tipos do componente COM para que as chamadas atravessem com êxito o limite do apartamento.

  • Altere o thread principal definindo o thread do cliente como STA ou MTA. Por exemplo, se o cliente C# chamar muitos componentes STA COM, você poderá evitar a empacotação entre apartamentos definindo o thread principal como STA.

    Nota

    Uma vez que o thread de um cliente C# é definido como STA, as chamadas para componentes MTA COM exigirão empacotamento entre apartamentos.

Para obter instruções sobre como selecionar explicitamente um modelo de apartamento, consulte Threading gerenciado e não gerenciado.

Marshalling Chamadas Remotas

Tal como acontece com o empacotamento entre apartamentos, o agrupamento COM está envolvido em cada chamada entre código gerenciado e não gerenciado sempre que os objetos residem em processos separados. Por exemplo:

  • Um cliente COM que invoca um servidor gerenciado em um host remoto usa COM distribuído (DCOM).
  • Um cliente gerenciado que invoca um servidor COM em um host remoto usa DCOM.

A ilustração a seguir mostra como o interop marshalling e o COM marshalling fornecem canais de comunicação através dos limites do processo e do host:

Cross-process marshalling

Preservando a identidade

O common language runtime preserva a identidade de referências gerenciadas e não gerenciadas. A ilustração a seguir mostra o fluxo de referências diretas não gerenciadas (linha superior) e referências gerenciadas diretas (linha inferior) entre os limites do processo e do host.

COM callable wrapper and runtime callable wrapper

Nesta ilustração:

  • Um cliente não gerenciado obtém uma referência a um objeto COM de um objeto gerenciado que obtém essa referência de um host remoto. O mecanismo de comunicação remota é DCOM.

  • Um cliente gerenciado obtém uma referência a um objeto gerenciado de um objeto COM que obtém essa referência de um host remoto. O mecanismo de comunicação remota é DCOM.

    Nota

    A biblioteca de tipos exportados do servidor gerenciado deve ser registrada.

O número de limites do processo entre chamador e destinatário é irrelevante; A mesma referência direta ocorre para chamadas dentro e fora do processo.

Comunicação remota gerenciada

O tempo de execução também fornece comunicação remota gerenciada, que você pode usar para estabelecer um canal de comunicação entre objetos gerenciados através dos limites do processo e do host. A comunicação remota gerenciada pode acomodar um firewall entre os componentes de comunicação, como mostra a ilustração a seguir:

SOAP or TcpChannel Chamadas remotas através de firewalls usando SOAP ou a classe TcpChannel

Algumas chamadas não gerenciadas podem ser canalizadas por meio de SOAP, como as chamadas entre componentes atendidos e COM.

Title Description
Comportamento de Marshalling Padrão Descreve as regras que o serviço de interoperabilidade usa para organizar dados.
Marshalling Data with Platform Invoke Descreve como declarar parâmetros de método e passar argumentos para funções exportadas por bibliotecas não gerenciadas.
Marshalling de dados com interoperabilidade COM Descreve como personalizar wrappers COM para alterar o comportamento de empacotamento.
Como: Migrar DCOM de código gerenciado para WCF Descreve como migrar do DCOM para o WCF.
Como: Mapear HRESULTs e exceções Descreve como mapear exceções personalizadas para HRESULTs e fornece o mapeamento completo de cada HRESULT para sua classe de exceção comparável no .NET Framework.
Interoperando usando tipos genéricos Descreve quais ações são suportadas ao usar tipos genéricos para interoperabilidade COM.
Interoperando com código não gerenciado Descreve os serviços de interoperabilidade fornecidos pelo Common Language Runtime.
Interoperabilidade COM avançada Fornece links para mais informações sobre como incorporar componentes COM em seu aplicativo .NET Framework.
Considerações de design para interoperação Fornece dicas para escrever componentes COM integrados.

Referência

System.Runtime.InteropServices