Verwendung der globalen Schnittstellentabelle
Wenn Sie einen Schnittstellenzeiger mehrmals zwischen Apartments in einem Prozess aufheben, können Sie die IGlobalInterfaceTable-Schnittstelle verwenden. Bei anderen Techniken müssten Sie jedes Mal erneut zusammensalten.
Hinweis
Wenn der Schnittstellenzeiger nur einmal unmarshaled ist, sollten Sie die CoMarshalInterThreadInterfaceInStream-Funktion verwenden. Sie kann auch verwendet werden, um einen Schnittstellenzeiger von einem Thread an einen anderen Thread im gleichen 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 erfüllt sind:
- Ein prozessübergreifendes agiles Objekt aggregiert den Freethread-Marshaller.
- Dieses agile Objekt enthält (als Membervariablen) auch Schnittstellenzeiger auf andere Objekte, die nicht agil sind und den Freethread-Marshaller nicht aggregieren.
Wenn in dieser Situation das äußere Objekt in ein anderes Apartment gemarshallt wird und die Anwendung darauf aufruft und das Objekt versucht, für einen seiner Membervariablenschnittstellenzeiger aufzurufen, die kein Freethreading sind oder Proxys für Objekte in anderen Apartments sind, erhalten sie möglicherweise falsche Ergebnisse oder den Fehler RPC _ E _ WRONG _ THREAD. Dieser Fehler tritt auf, weil die innere Schnittstelle nur aus dem Apartment aufgerufen werden kann, in dem sie zum ersten Mal in der Membervariablen gespeichert wurde.
Um dieses Problem zu lösen, sollte das äußere Objekt, das den Freethread-Marshaller aggregiert, IGlobalInterfaceTable::RegisterInterfaceInGlobal auf der inneren Schnittstelle aufrufen und das resultierende Cookie in seiner Membervariablen speichern, anstatt den eigentlichen Schnittstellenzeiger zu speichern. Wenn das äußere Objekt für den Schnittstellenzeiger eines inneren Objekts aufrufen möchte, sollte es IGlobalInterfaceTable::GetInterfaceFromGlobalaufrufen, den zurückgegebenen Schnittstellenzeiger verwenden und dann freigeben. Wenn das äußere Objekt entfernt wird, sollte es IGlobalInterfaceTable::RevokeInterfaceFromGlobal aufrufen, um die Schnittstelle aus der globalen Schnittstellentabelle zu entfernen.