Quando usare la tabella dell'interfaccia globale
Se si deve de-marshalling un puntatore di interfaccia più volte tra appartamenti in un processo, è possibile utilizzare l'interfaccia IGlobalInterfaceTable. Con altre tecniche, dovresti ricomporre ogni volta.
Nota
Se il puntatore dell'interfaccia viene smarshallato una sola volta, è possibile utilizzare la funzione CoMarshalInterThreadInterfaceInStream. Può anche essere usato per passare un puntatore di interfaccia da un thread a un altro thread nello stesso processo.
L'interfacciaIGlobalInterfaceTablerende più semplice un altro problema precedentemente difficile per il programmatore. Questo problema si verifica quando si applicano le condizioni seguenti:
- Un oggetto agile in-processo aggrega il marshaler a thread libero.
- Questo stesso oggetto agile contiene anche puntatori di interfaccia (come variabili membro) ad altri oggetti che non sono agili e non aggregano il marshalling a thread libero.
In questa situazione, se l'oggetto esterno viene sottoposto a marshalling in un altro appartamento e l'applicazione lo richiama, e l'oggetto tenta di utilizzare uno dei suoi puntatori di interfaccia variabile membro che non supportano il multi-threading o sono proxy verso 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 marshaler a thread libero deve chiamare IGlobalInterfaceTable::RegisterInterfaceInGlobal sull'interfaccia interna e archiviare il cookie risultante nella sua variabile membro, invece di archiviare il puntatore effettivo dell'interfaccia. Quando l'oggetto esterno vuole chiamare sul puntatore dell'interfaccia di un oggetto interno, deve chiamare IGlobalInterfaceTable::GetInterfaceFromGlobal, usare il puntatore all'interfaccia restituito e rilasciarlo. Quando l'oggetto esterno viene rimosso, deve chiamare IGlobalInterfaceTable::RevokeInterfaceFromGlobal per rimuovere l'interfaccia dalla tabella dell'interfaccia globale.
Argomenti correlati