Não posso deixar de postar isso, embora não seja uma resposta direta para a pergunta.
Há um brilhante artigo da MSKB da idade dourada de Com: Informações: Descrições e funcionamentos de modelos de encadeamento OLE. Ainda lá, e tem todas as informações relevantes. O ponto é que você não deve se preocupar se há marechaling ou não, se você seguir as regras. Basta registrar seu objeto como ThreadingModel=Both
, agregar o marechaler de thread livre com CoCreateFreeThreadedMarshaler
, e ser feito. Com fará o marechaling, se necessário, da melhor maneira possível. Dependendo do modelo de apartamento do cliente, o código do cliente pode receber o ponteiro direto da sua interface, se seguir as regras também.
Qualquer interface "alienígena" que você possa receber quando um método da sua interface for chamado será válido no escopo da chamada, porque você permanece no mesmo thread. Se você não precisa armazená -lo, isso é tudo o que importa.
Se, porém CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
:
Para armazená -lo:
- Entrar na seção crítica;
- ligar
CoMarshalInterThreadInterfaceInStream
e armazenar o IStream
ponteiro em um campo membro;
- Deixar seção crítica;
Para recuperá -lo
- Entrar na seção crítica;
- ligar
CoGetInterfaceAndReleaseStream
Para recuperar a interface
- ligar
CoMarshalInterThreadInterfaceInStream
e armazená -lo novamente como IStream
Para qualquer uso futuro
- Deixar seção crítica;
- Use a interface no escopo da chamada atual
Para lançar:
- Quando você não precisa mais mantê -lo, basta liberar o armazenado
IStream
(dentro da seção crítica).
Se o objeto "alienígena" também for livre e as coisas estão acontecendo dentro do mesmo processo, você provavelmente estará lidando com um ponteiro de interface direto depois CoGetInterfaceAndReleaseStream
. No entanto, você não deve fazer suposições e realmente não precisa saber se o objeto com o qual lidar é o objeto original ou um proxy do marshaller.
Isso pode ser um pouco otimizado usando CoMarshalInterface
W/ MSHLFLAGS_TABLESTRONG
/ CoUnmarshalInterface
/ IStream::Seek(0, 0)
/ CoReleaseMarshalData
ao invés de CoGetInterfaceAndReleaseStream
/CoGetInterfaceAndReleaseStream
, para solucionar a mesma interface quantas vezes o necessário sem liberar o fluxo.
Cenários de cache mais complexos (e possivelmente mais eficientes) são possíveis, envolvendo o armazenamento local. No entanto, acredito que isso seria um exagero. Eu não fiz nenhum tempo, mas acho que a sobrecarga de CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
é realmente baixo.
Dito isto, se você precisar manter um estado que Armazra quaisquer recursos ou objetos que possam exigir afinidade do encadeamento, além de interfaces comi mencionadas, você não deveria Marque seu objeto como ThreadingModel=Both
ou agregar o FTM.