Como passar um ponteiro de interface para um segmento?
-
21-08-2019 - |
Pergunta
Nota:
- Usando matéria-Win32 CreateTheard () API
- No MFC
- Uma interface é simplesmente um ponteiro para uma vtable
Pergunta:
- Como passar um ponteiro de interface para um segmento?
Ilustração:
IS8Simulation *pis8 = NULL;
...
CoCreateInstance(
clsid,
NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IS8Simulation),
(void **) &pis8);
...
hThread = CreateThread(
NULL,
0,
SecondaryThread,
//interface pointer pis8
0,
&dwGenericThreadID);
...
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
//using iValue accordingly
//E.g.: iValue->Open
Saudações
Solução
Como foi dito abaixo, passando um ponteiro de interface COM
entre threads em não segura.
Assumindo que você saiba o que está fazendo:
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) pis8
0,
&dwGenericThreadID);
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
((IS8Simulation*) iValue)->Open();
}
Passe versão segura:
void MainThread()
{
IStream* psis8;
HRESULT res = CoMarshalInterThreadInterfaceInStream (IID_IS8SIMULATION, pis8, &psis8);
if (FAILED(res))
return;
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) psis8
0,
&dwGenericThreadID
);
}
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
IS8Simulation* pis8;
HRESULT res = CoGetInterfaceAndReleaseStream((IStream*) iValue, IID_IS8SIMULATION, &pis8);
if (FAILED(res))
return (DWORD) res;
pis8->Open();
}
Outras dicas
Se a interface na sua pergunta é uma interface COM, a abordagem dada pela Quassnoi pode não ser suficiente. Você tem que prestar atenção ao enfiar-modelo do objeto COM em uso. Se o thread secundário vão participar de um apartamento COM separado daquele que seu objeto COM foi criado, e se esse objeto não é apartamento ágil , você vai precisar para organizar esse ponteiro interface para que o thread secundário recebe um proxy, e não um ponteiro direto para o objeto.
Um objeto COM é normalmente feita apartamento de ágil usando uma implementação especial de IMarshal. A abordagem mais simples é agregar o threaded Marshaler gratuito.
Alguns links úteis ...
Update: Sobre o Livre-threaded empacotador ...
É claro desde comentários sobre este tema que algumas pessoas recomendo que você nunca tocar o FTM. Enquanto "Eficaz COM" é um livro excelente, acho que algumas das suas recomendações estão abertas à interpretação. Ponto 33 diz: "Cuidado com o FTM"; ela não diz "Nunca utilizar o FTM". Muito sabiamente aconselha cautela especialmente quando o seu objeto apartamento de ágil mantém referências a outros objetos, pois eles podem não ser apartamento-ágil. Então, realmente o conselho é: pensar cuidadosamente na construção de objetos de apartamentos-ágil, ou não usar o FTM para alcançar sua agilidade. Se você tem certeza que você pode construir um objeto apartamento de ágil, não vejo nenhuma razão para que você não usaria o FTM para conseguir isso.
Você basicamente precisa fazer o seguinte:
-
CoMashalInterThreadInterfaceInStream
==> você ter uma interface IStream. - passar esse IStream para o segmento, por exemplo, referido como Quassnoi.
- em SecondaryThread, chamada
CoGetInterfaceAndReleaseStream
para obter a interface (ou um proxy para que, se necessário).
Não solte a interface IStream a menos que criar o fio falhar, e não sair do thread até yu têm chamado CoGetInterfaceAndReleaseStream
.
COM tempo de execução irá criar o proxy para você automaticamente. Os garante que, por exemplo, de proxy um componente COM segmentação de compartimento é chamado no thread que o criou. No entanto, isso também requer que:
- A interface é IDispatch, ou proxy / stub componentes estão registados para a interface
- o threadthat criou o componente tem um loop e processos mensagem mensagens