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

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top