Question

Remarque:

  • Utiliser API Win32 brut CreateTheard ()
  • Non MFC
  • Une interface est tout simplement un pointeur sur un vtable

Question:

  • Comment passer un pointeur d'interface à un fil?

Illustration:

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

Cordialement

Était-ce utile?

La solution

Comme il a été indiqué ci-dessous, le passage d'un pointeur d'interface entre les threads en COM pas sûr.

En supposant que vous savez ce que vous faites:

hThread = CreateThread(
                NULL,
                        0,
                        SecondaryThread,
                        (LPVOID) pis8
                        0,
                        &dwGenericThreadID);

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
   ((IS8Simulation*) iValue)->Open();
}

Discussion version sécurisée:

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();
}

Autres conseils

Si l'interface de votre question est une interface COM, l'approche donnée par Quassnoi pourrait ne pas être suffisante. Vous devez prêter attention au filetage modèle de l'objet COM utilisé. Si le thread secondaire rejoindra un appartement COM distinct de celui que votre objet COM a été créé en, et si cet objet est pas appartement agile , vous aurez besoin de maréchal que pointeur d'interface de sorte que la thread secondaire obtient un proxy, et non un pointeur direct vers l'objet.

Un objet COM est normalement fait appartement agile en utilisant une implémentation spéciale de IMarshal. L'approche la plus simple consiste à agréger les Free Threaded Marshaler.

Quelques liens utiles ...

Mise à jour: A propos de la Marshaler Free-thread ...

Il est clair de commentaires sur ce sujet que certaines personnes vous recommandons de ne jamais toucher l'FTM. Bien que « efficace COM » est un excellent livre, je pense que certaines de ses recommandations sont ouvertes à l'interprétation. Article 33 dit: « Méfiez-vous de la FTM »; il ne dit pas « Ne jamais utiliser le FTM ». Très sagement conseille la prudence en particulier lorsque votre objet appartement agile contient des références à d'autres objets, car ils pourraient ne pas être agile appartement. Alors, vraiment les conseils est: bien réfléchir lors de la construction des objets d'habitation agile, si oui ou non ils utilisent le FTM pour atteindre leur agilité. Si vous êtes sûr que vous pouvez construire un objet appartement agile, je ne vois aucune raison pour laquelle vous ne seriez pas utiliser le FTM pour y parvenir.

Vous devez essentiellement faire ce qui suit:

  • CoMashalInterThreadInterfaceInStream ==> vous obtenez une interface IStream.
  • passer que IStream au fil, par exemple, en tant que dit Quassnoi.
  • dans SecondaryThread, appelez pour obtenir l'CoGetInterfaceAndReleaseStream interface (ou un proxy, si nécessaire).

Ne pas libérer l'interface IStream à moins que la création du fil échoue, et ne pas quitter le fil jusqu'à ce que yu ont appelé <=>.

runtime COM crée le proxy automatiquement pour vous. La procuration assure que par exemple un composant COM appartement-thread est appelé sur le fil qui l'a créé. Toutefois, cela exige également que:

  • L'interface est IDispatch, ou proxy / stub composants sont enregistrés pour l'interface
  • le threadthat créé le composant comporte une boucle de message et traite les messages
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top