Come passare un puntatore ad un filo?
-
21-08-2019 - |
Domanda
Nota:
- Uso greggio Win32 CreateTheard () API
- Nessun MFC
- Un'interfaccia è semplicemente un puntatore ad una vtable
Domanda:
- Come passare un puntatore ad una discussione?
Illustrazione:
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
Saluti
Soluzione
Come già indicato sotto, passando un puntatore all'interfaccia COM
tra i thread in non sicuro.
Supponendo che si sa cosa si sta facendo:
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) pis8
0,
&dwGenericThreadID);
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
((IS8Simulation*) iValue)->Open();
}
Discussione versione sicura:
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();
}
Altri suggerimenti
Se l'interfaccia in questione è un interfaccia COM, l'approccio data dal Quassnoi potrebbe non essere sufficiente. Bisogna prestare attenzione al threading-modello dell'oggetto COM in uso. Se il thread secondario si unirà un appartamento COM separato da quello che l'oggetto COM è stato creato in, e se questo oggetto non è appartamento-agile , avrete bisogno di maresciallo che puntatore di interfaccia in modo che il thread secondario ottiene un proxy, e non un puntatore diretto all'oggetto.
Un oggetto COM viene normalmente fatto appartamento-agile utilizzando una speciale implementazione IMarshal. L'approccio più semplice è quello di aggregare il Free Threaded Marshaler.
Alcuni link utili ...
Aggiornamento: A proposito del Marshaler Free-threaded ...
E 'chiaro dai commenti su questo argomento che alcune persone avrebbero consiglia di non toccare mai il FTM. Mentre "efficace COM" è un ottimo libro, penso che alcune delle sue raccomandazioni sono aperti all'interpretazione. Articolo 33 dice: "Attenzione la FTM"; non dice "Non usare mai il FTM". Molto saggiamente si raccomanda cautela soprattutto quando l'oggetto appartamento-agile detiene riferimenti ad altri oggetti, perché potrebbero non essere appartamento-agile. Quindi, in realtà il consiglio è: riflettere attentamente quando si costruisce oggetti appartamento-agile, anche se non utilizzano il FTM per raggiungere la loro agilità. Se sei sicuro si può costruire un oggetto appartamento-agile, non vedo alcuna ragione per cui non può usare il FTM per raggiungere questo obiettivo.
È fondamentalmente bisogno di fare quanto segue:
-
CoMashalInterThreadInterfaceInStream
==> si ottiene un'interfaccia IStream. - passare che IStream al filo, ad esempio come detto Quassnoi.
- in SecondaryThread, chiamare
CoGetInterfaceAndReleaseStream
per ottenere l'interfaccia (o un proxy ad esso, se necessario).
Non rilasciare l'interfaccia IStream a meno che la creazione del filo non riesce e non uscire il filo fino yu hanno chiamato <=>.
runtime COM creerà il proxy per voi automaticamente. Il proxy assicura che ad esempio un componente COM di threading Apartment è chiamato sul thread che lo ha creato. Tuttavia, questo richiede anche che:
- L'interfaccia è IDispatch, o un proxy / stub componenti sono registrati per l'interfaccia
- il threadthat creato il componente è un ciclo di messaggi e elabora i messaggi