Wann sollte die globale Schnittstellentabelle verwendet werden?

Wenn Sie einen Schnittstellenzeiger mehrmals zwischen Wohnungen in einem Prozess aufheben, können Sie die IGlobalInterfaceTable-Schnittstelle verwenden. Mit anderen Techniken müssten Sie jedes Mal erneut zusammenmemmen.

Hinweis

Wenn der Schnittstellenzeiger nur einmal aufgehoben wird, können Sie die CoMarshalInterThreadInterfaceInStream-Funktion verwenden. Es kann auch verwendet werden, um einen Schnittstellenzeiger von einem Thread an einen anderen Thread im selben Prozess zu übergeben.

 

Die IGlobalInterfaceTable-Schnittstelle vereinfacht auch ein weiteres zuvor schwieriges Problem für den Programmierer. Dieses Problem tritt auf, wenn die folgenden Bedingungen gelten:

  • Ein prozessinternes agiles Objekt aggregiert den Freethread-Marshaller.
  • Dasselbe agile Objekt enthält auch (als Membervariablen) Schnittstellenzeiger auf andere Objekte, die nicht agil sind und den Freethread-Marshaller nicht aggregieren.

Wenn das äußere Objekt in einem anderen Apartment gemarst wird und die Anwendung es aufruft, und das Objekt versucht, einen seiner Elementvariablenschnittstellenzeiger aufzurufen, die nicht Freithreads sind oder Proxys für Objekte in anderen Wohnungen sind, erhält es möglicherweise falsche Ergebnisse oder der Fehler RPC_E_WRONG_THREAD. Dieser Fehler tritt auf, weil die innere Schnittstelle nur von der Wohnung aufgerufen werden kann, in der sie zuerst in der Membervariable gespeichert wurde.

Um dieses Problem zu beheben, sollte das äußere Objekt, das den Freethread-Marshaller aggregiert, IGlobalInterfaceTable::RegisterInterfaceInGlobal auf der inneren Schnittstelle aufrufen und das resultierende Cookie in seiner Membervariable speichern, anstatt den tatsächlichen Schnittstellenzeiger zu speichern. Wenn das äußere Objekt den Schnittstellenzeiger eines inneren Objekts aufrufen möchte, sollte es IGlobalInterfaceTable::GetInterfaceFromGlobal aufrufen, den zurückgegebenen Schnittstellenzeiger verwenden und ihn dann freigeben. Wenn das äußere Objekt entfernt wird, sollte es IGlobalInterfaceTable::RevokeInterfaceFromGlobal aufrufen, um die Schnittstelle aus der globalen Schnittstellentabelle zu entfernen.

Erstellen der globalen Schnittstellentabelle