COM è un meccanismo che consente il riutilizzo di oggetti (o meglio componenti), indipendentemente dai linguaggi utilizzati dal programmatore che ha implementato il componente e dal programmatore che lo utilizza, e indipendentemente dal fatto che il componente sia stato implementato nel programma del cliente o altrove sulla macchina (o sulla rete).
In generale, ogni componente COM fornisce un'implementazione di una o più interfacce. Tali interfacce sono definite in modo indipendente dal linguaggio utilizzando IDL (Interface Definition Language) . Ad esempio, una delle interfacce fondamentali in COM, IUnknown , è definita in questo modo:
interface IUnknown
{
virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0;
virtual ULONG AddRef(void) = 0;
virtual ULONG Release(void) = 0;
};
Questa piccola interfaccia è fondamentale in COM, perché ogni componente COM deve implementarla. Definisce due aspetti importanti del macchinario COM:
QueryInterface
consente di chiamare il codice per ottenere un'implementazione per un'interfaccia nota. In COM, le interfacce sono referenziate da GUID (noti anche come identificatori di interfaccia, IID). Se un oggetto implementa più interfacce, è così che il codice client ottiene un riferimento a ciascuna di queste interfacce. Agisce come una sorta di casting operator, se vuoi.
AddRef()
e Release()
implementare il meccanismo di gestione della memoria per gli oggetti COM. Come suggerisce il nome, il modello più comune è il meccanismo di conteggio dei riferimenti, in cui un'istanza viene distrutta dopo che l'ultimo client ha rilasciato il suo riferimento ad essa.
Tutti i componenti COM vengono registrati con il sistema al momento dell'installazione. Se un programmatore desidera utilizzare un determinato componente, deve:
- Assicurati che il componente sia installato in una posizione raggiungibile. La maggior parte delle volte si trova nel sistema dell'applicazione in esecuzione, ma COM + consente anche ai componenti di esistere sui computer remoti.
- Conosci il GUID del componente dato. Con questo GUID, il client può quindi chiedere al sistema di creare un'istanza del componente (in C, viene chiamata la funzione per farlo
CoCreateInstance()
). Puoi guardare nel registro sotto HKEY_CLASSES_ROOT\CLSID
: ogni GUID al suo interno è (molto probabilmente) un identificatore per un componente o un'interfaccia COM e le voci sotto quella chiave dicono al sistema come dovrebbe essere istanziato.
La macchina COM è estremamente complessa. Ad esempio, l'implementazione o l'utilizzo di componenti COM in C richiede una quantità enorme di lavoro, ma linguaggi di livello superiore come Visual Basic hanno fatto molto per facilitare l'implementazione e l'utilizzo dei componenti COM. I vantaggi sono comunque molto reali. Rende possibile scrivere un'applicazione in, ad esempio, Visual Basic, ma implementare comunque gli algoritmi critici per le prestazioni in C o C ++ come oggetti COM, che possono essere utilizzati direttamente dal codice VB. Il sistema si occupa del marshalling degli argomenti delle chiamate di metodo, passandoli attraverso thread, processi e connessioni di rete secondo necessità, in modo che il codice client abbia l'impressione di usare un oggetto normale.
Molte parti fondamentali di Windows sono basate su COM. Windows Explorer (il file manager), ad esempio, è fondamentalmente una shell vuota. Definisce una serie di interfacce COM per la navigazione e la visualizzazione di gerarchie ad albero e tutto il codice che effettivamente visualizza "Risorse del computer", le unità, le cartelle e i file è un insieme di componenti COM che implementano tali interfacce.
Con l'avvento di .NET, COM sta lentamente diventando obsoleto.