Partager via


Quand utiliser la table d’interface globale

Si vous démarshalez plusieurs fois un pointeur d’interface entre des appartements dans un processus, vous pouvez utiliser l’interface IGlobalInterfaceTable . Avec d’autres techniques, il faudrait remarshaler à chaque fois.

Notes

Si le pointeur d’interface n’est démarshalé qu’une seule fois, vous pouvez utiliser la fonction CoMarshalInterThreadInterfaceInStream . Il peut également être utilisé pour passer un pointeur d’interface d’un thread à un autre thread dans le même processus.

 

L’interface IGlobalInterfaceTable simplifie également un autre problème précédemment difficile pour le programmeur. Ce problème se produit lorsque les conditions suivantes s’appliquent :

  • Un objet agile in-process agrège le marshaler à thread libre.
  • Ce même objet agile contient également (en tant que variables membres) des pointeurs d’interface vers d’autres objets qui ne sont pas agiles et qui n’agrègent pas le marshaler à thread libre.

Dans ce cas, si l’objet externe est marshalé vers un autre appartement et que l’application appelle dessus, et que l’objet tente d’appeler sur l’un de ses pointeurs d’interface de variable membre qui ne sont pas à thread libre ou sont des proxys vers des objets dans d’autres appartements, il peut obtenir des résultats incorrects ou l’erreur RPC_E_WRONG_THREAD. Cette erreur se produit car l’interface interne est conçue pour être appelée uniquement à partir de l’appartement dans lequel elle a été stockée pour la première fois dans la variable membre.

Pour résoudre ce problème, l’objet externe agrégeant le marshaleur à thread libre doit appeler IGlobalInterfaceTable::RegisterInterfaceInGlobal sur l’interface interne et stocker le cookie résultant dans sa variable membre, au lieu de stocker le pointeur d’interface réel. Lorsque l’objet externe souhaite appeler sur le pointeur d’interface d’un objet interne, il doit appeler IGlobalInterfaceTable::GetInterfaceFromGlobal, utiliser le pointeur d’interface retourné, puis le libérer. Lorsque l’objet externe disparaît, il doit appeler IGlobalInterfaceTable::RevokeInterfaceFromGlobal pour supprimer l’interface de la table d’interface globale.

Création de la table d’interface globale