Quando usare la tabella dell'interfaccia globale
Se si annulla ilmarshaling di un puntatore di interfaccia più volte tra appartamenti in un processo, è possibile usare l'interfaccia IGlobalInterfaceTable . Con altre tecniche, dovresti rimarare ogni volta.
Nota
Se il puntatore dell'interfaccia viene scollegato una sola volta, è possibile usare la funzione CoMarshalInterThreadInterfaceInStream. Può anche essere usato per passare un puntatore di interfaccia da un thread a un altro thread nello stesso processo.
L'interfaccia IGlobalInterfaceTable rende anche più semplice un altro problema precedentemente difficile per il programmatore. Questo problema si verifica quando si applicano le condizioni seguenti:
- Un oggetto Agile in-process aggrega il gestore di marshalling a thread libero.
- Questo stesso oggetto Agile contiene anche puntatori di interfaccia (come variabili membro) ad altri oggetti che non sono agile e non aggregano il gestore di marshalling a thread libero.
In questa situazione, se l'oggetto esterno viene sottoposto a marshalling in un altro apartment e l'applicazione lo chiama e l'oggetto tenta di chiamare su uno dei puntatori a interfaccia variabile membro che non sono a thread libero o sono proxy a oggetti in altri appartamenti, potrebbe ottenere risultati non corretti o l'errore RPC_E_WRONG_THREAD. Questo errore si verifica perché l'interfaccia interna è progettata per essere chiamata solo dall'apartment in cui è stata archiviata per la prima volta nella variabile membro.
Per risolvere questo problema, l'oggetto esterno che aggrega il gestore di marshalling a thread libero deve chiamare IGlobalInterfaceTable::RegisterInterfaceInGlobal nell'interfaccia interna e archiviare il cookie risultante nella variabile membro, anziché archiviare il puntatore di interfaccia effettivo. Quando l'oggetto esterno vuole chiamare sul puntatore di interfaccia di un oggetto interno, deve chiamare IGlobalInterfaceTable::GetInterfaceFromGlobal, usare il puntatore all'interfaccia restituito e quindi rilasciarlo. Quando l'oggetto esterno viene rimosso, deve chiamare IGlobalInterfaceTable::RevokeInterfaceFromGlobal per rimuovere l'interfaccia dalla tabella dell'interfaccia globale.
Argomenti correlati