Component Object Model (COM) &
Distributed COM (DCOM)
Elaborazione Distribuita
(anni ’80)
Appunti di Windows &
Dynamic Data Exchange (DDE)
(1987)
Object Linking and Embedding 1 (OLE 1)
& Dynamic Data Exchange (DDE)
(1992, 1993)
Open Software Foundation (OSF)
Remote Procedure Calls (RPC)
(1992)
COM, OLE2, ActiveX
(Windows NT 4.0)
(1995)
DCOM (1996)
Ragioni dello sviluppo COM
 Applicazioni software di dimensioni sempre più grandi
Lunghi tempi per lo sviluppo e la manutenzione
 Difficoltà nel rimuovere o aggiornare singole
applicazioni che interagiscono con altre applicazioni
 Necessità di:
Semplificare la progettazione e lo sviluppo di applicativi
Facilitare e standardizzare l'interazione tra applicazioni di
diversi produttori
Caratteristiche del modello COM
COM è una specifica
http://www.microsoft.com/com/resources/comdocs.asp
COM è una “filosofia di programmazione”
Programmazione basata su componenti riciclabili
COM è uno standard di interoperabilità binaria
COM è un “collante” tra componenti, permettendo la loro
interazione
Caratteristiche del modello COM
 Componente
 una parte di software riutilizzabile in forma binaria (non è
un codice sorgente !!!)
 Suddivisione di un progetto in componenti
 I componenti possono essere facilmente integrati con
componenti prodotti da altri fornitori
 Un componente permette di accedere alle proprie
funzionalità tramite le “interfacce”
 Esempi di componenti: pulsanti, correttori ortografici
Caratteristiche del modello COM
 L’utilizzo di un componente da parte di una
applicazione non comporta la ricompilazione, visto
che il componente che deve essere riutilizzato è già in
versione binaria
 Ad esempio un word processor che usa un correttore
ortografico
 Un componente è riutilizzabile
 Chi produce un componente può riutilizzarne uno già
esistente, utilizzando due tecniche: containment e
aggregation
Caratteristiche del modello COM
 Gestione delle versioni
 Si è superato il problema delle dll:
un programma che utilizza una dll può interrompersi se trova una
versione diversa di dll
 In COM non è possibile cambiare le caratteristiche
("interfaccia") dei componenti già esistenti.
 La nuova versione di un componente COM deve
presentare le stesse interfacce, aggiungendone altre
Ad esempio se voglio realizzare un correttore ortografico diverso
da quello offerto da word, devo garantire le stesse interfacce
originarie, aggiungendone altre se voglio
Tecnologie ActiveX e OLE 2
 Sono tecnologie create sulla base di COM e della sua
architettura
 ActiveX utilizza anche la tecnologia OLE v.2.0
 La principale e visibile caratteristica dei documenti
ActiveX è la possibilità di aprire una finestra
all’interno di un’altra applicazione
Ad esempio Explorer nei confronti dei documenti Word o
Acrobat
ActiveX
OLE 2
COM
Oggetti COM
 Ogni oggetto COM è un’istanza di una particolare
classe
 Ogni oggetto COM presenta una o più interfacce
 Ogni interfaccia include uno o più metodi che
possono essere invocati dal programma client
 Per invocare uno di questi metodi il client deve
possedere un puntatore all’interfaccia che contiene i
metodi
Client
AddToDictionary()
RemoveFromDictionary()
Oggetto COM
Interfaccia
Metodi
Interfacce degli Oggetti COM
 Ogni interfaccia ha due nomi:
 Stringa di caratteri. Deve iniziare con la lettera “I”
 Globally Unique Identifier (GUID), chiamata Interface
Identifier (IID) o Universal Unique Identifiers (UUID)
 GUID è di 16 byte ed è ottenuta eseguendo un apposito tool
 GUID contiene un time stamp (tutti i GUID generati nella stessa
macchina saranno diversi)
 GUID contiene il MAC address (o un numero casuale se non vi è
una scheda) per differenziare GUID generati da macchine diverse
 La specifica delle interfacce (non l’implementazione)
avviene in un linguaggio comune: Interface
Definition Language (IDL)
 Deriva dall'IDL usato in Microsoft RPC
Esempio di Interface Definition Language
[object,
uuid(E7CD0D00-1827-11CF-9946-444553540000)]
interface IMyInterface : IUnknown {
import “unknwn.idl”;
HRESULT LookUpInt([in] int c, [out] boolean *found);
HRESULT SumOfIntegers([in] myinteger[5], [out] int *sum);
}
 L'interfaccia IMyInterface eredita tutti i metodi definiti in IUnknown
 Un client in possesso del puntatore a IMyInterface può invocare anche i
metodi di IUnknown
 I metodi dell'interfaccia IUnknown devono essere sempre presenti !
 Il comando import specifica il file idl che descrive IUnknown
 LookUpInt e SumOfIntegers sono i metodi forniti dall'interfaccia
IMyInterface
 HRESULT è un valore di ritorno standard relativo al successo/insuccesso
 [in], [out] parametri formali ingresso e uscita (esistono anche quelli
ingresso/uscita [in, out])
Alcune Regole sulla Definizione delle
Interfacce
 Una volta che una interfaccia è stata definita e
rilasciata nel "mondo", essa non può più essere
cambiata.
 Non è possibile cambiare/aggiungere/modificare
metodi o parametri.
 L'unica soluzione è definire una nuova interfaccia
(nuovo nome e IID) che possiede gli stessi metodi
della vecchia interfaccia, aggiungendone altri nuovi.
Definizione delle Interfacce:
Standard binary format
 La descrizione dell'interfaccia non è sufficiente per il suo uso da
parte di un generico client
 Il client possiede solo il puntatore all'iterfaccia
 In genere per invocare un metodo, un client deve sapere come
fare (ciò in genere dipende dal linguaggio in cui è stato scritto il
metodo)
 Esiste una struttura binaria (SEMPRE LA STESSA) per
l'accesso ai metodi di una interfaccia di un oggetto COM.
 Standard binary interface format
 La presenza di uno standard binary interface format implica che
il client possa invocare un metodo di un oggetto senza dover
tener conto del linguaggio in cui è stato scritto il metodo stesso
Esempio di Interface Definition Language
Client
QueryInterface() { ……}
Pointer Method 1
AddRef() { ……}
Pointer Method 2
Release() { ……}
Puntatore
Interfaccia
Pointer Method 3
IMyInterface
Pointer Method 4
LookUpInt() { ……}
Pointer Method 5
SumOfInteger() { ……}
vtable
Internal
Pointer
to vtable
(1)
1) Metodi interfaccia IUnknown (sempre presenti)
2) Metodi interfaccia IMyInterface
(2)
Definizione delle Interfacce:
Standard binary format
 La struttura binaria appena vista suggerisce che la
realizzazione più "immediata" e "naturale" di un client COM
si ottiene utilizzando il C++
 è necessario implementare la gestione dei puntatori a
vtable per l'invocazione dei metodi
 Scrivere un client in C è possibile, ma più difficile
 L'assenza di meccanismi per la gestione dei puntatori in VB ha
determinato la necessità di creare una speciale interfaccia
vtable chiamata IDispatch
Interfaccia Fondamentale IUnknown
 Tutti gli oggetti COM la devono implementare
 Contiene tre metodi:
QueryInterface
AddRef
Release
Interfaccia Fondamentale IUnknown
Metodo QueryInterface
 Quando il client crea un oggetto COM (come ? si vedrà
dopo), riceve il puntatore ad una delle sue interfacce
(quella richiesta dal client)
 Con tale puntatore il client può invocare tutti i metodi
dell'interfaccia
 E se vuole invocare metodi appartenenti ad altre interfacce ?
 Ci sono casi in cui un client non crea un oggetto
COM, ma un altro client gli passa (cede) il puntatore ad
un'interfaccia di un oggetto COM già creato
 Con tale puntatore il client può invocare tutti i metodi
dell'interfaccia
 E se vuole invocare metodi appartenenti ad altre interfacce ?
Interfaccia Fondamentale IUnknown
Metodo QueryInterface
 Attraverso il puntatore all’interfaccia, il client accede al metodo
IUnknown::QueryInterface
 Specifica l’IID dell’interfaccia che gli necessita
 Se l’oggetto COM supporta l’interfaccia richiesta, il client riceverà il
puntatore all’interfaccia richiesta e potrà utilizzarne i metodi.
Altrimenti passerà NULL
1. Il Client usa il puntatore a A per
richiedere il puntatore a B, invocando la
QueryInterface (IID_B)
A
Client
2. L'Oggetto ritorna il puntatore a B
B
3. Il Client può invocare i metodi
dall'interfaccia B
Oggetto COM
Interfaccia Fondamentale IUnknown
Esempio di Utilizzo Metodo QueryInterface
 Supponiamo che esista un tool di analisi di testo implementato come
oggetto COM e che esso abbia un'interfaccia ISpellCheck
 Una volta installato l'oggetto nel mio sistema, il mio word processor (e
qualunque altro client) lo può utilizzare: interroga la QueryInterface e
chiede del puntatore a ISpellCheck
 Supponiamo che venga rilasciata una nuova versione dell'oggetto che ora
comprende anche l'interfaccia IThesaurus (semantica & sinonimi)
 Se uso il nuovo oggetto con l'esistente versione di word allora la nuova
interfaccia sarà del tutto ignorata
 Installando la nuova release del word processor, esso potrà chiedere sia il
puntatore a ISpellCheck sia a IThesaurus (tramite la QueryInterface)
 Se installo la nuova versione di word e mantengo il vecchio oggetto, tutto
funziona ancora bene, perché se il mio word chiederà alla QueryInterface il
puntatore a IThesaurus, otterrà NULL e l'opzione Thesaurus nel menù sarà
disabilitata
Tipi di Componenti
 Ogni oggetto COM è implementato dentro un Server
 Il Server supporta più oggetti di una determinata classe
 Il Server contiene il codice dei metodi delle interfacce
dell'oggetto
 Il Server ha il compito di creare l'oggetto
 Gestisce i dati di ciascun oggetto
 E' possibile avere tre diversi tipi di oggetti COM in base al tipo
di Server che li supporta:
 In-Process
 Local
 Remote
 Dal punto di vista del Client non vi è alcuna differenza
Tipi di Componenti
 Componenti In-process
 Il Server In-Process condivide lo stesso spazio degli
indirizzamenti del Client
 Il Server In-Process viene implementato come dll
 Vantaggio: velocità di elaborazione (nessun passaggio di
contesto)
 Svantaggio: essendo una dll e non exe, può essere
impiegato solo nel contesto di un programma chiamante e
non può essere eseguito come applicazione autonoma
Tipi di Componenti
 Componenti Locali
 Il Server risiede sullo stesso computer del Client, ma viene
eseguito come processo autonomo (spazio di indirizzi
differente)
 Il Server locale viene implementato come exe
 Svantaggio: cambio di contesto dal processo chiamante al
componente
 Componenti Remoti
 Il Server risiede su un computer diverso da quello in cui
viene fatto eseguire il client (processo che utilizza il
componente)
 Lo scambio informativo remoto viene supportato da
DCOM
Creazione di un Oggetto COM
 Finora si è assunto che un client possegga un
puntatore ad una interfaccia iniziale di un oggetto
COM
 Dobbiamo capire come sia possibile creare un
oggetto COM e come un client possa acquisire il
puntatore ad una delle interfacce di tale oggetto
 La creazione di un oggetto COM è basata su:
Esistenza di Class Identifier (CLSID).
 Ogni oggetto COM è una istanza di una classe
 Ogni classe è identificata da un Class Identifier
(CLSID)
Esistenza di una COM Library di supporto
Creazione di un Oggetto COM:
COM Library
 Ogni sistema che supporta COM deve fornire
un'implementazione della COM Library
 La COM Library fornisce funzioni di supporto ad
oggetti COM e ai client
 ad esempio quelle per creare un oggetto COM
 Le funzioni della COM Library sono accessibili
tramite semplici chiamate di funzioni
 non si usano metodi delle interfacce COM
 Il nome di una funzione della COM Library
generalmente inizia con il prefisso Co ad esempio CoCreateInstance
Creazione di un Oggetto COM:
COM Library
 La creazione di un oggetto COM implica la
produzione di una istanza della classe dell'oggetto
 Ciò viene realizzato tramite l'avvio del Server
relativo alla classe stessa
 Tale Server è l'unico in grado di istanziare l'oggetto COM
 E' necessario avviarlo solo per la prima istanza
dell'oggetto
 E' compito della COM Library avviare il Server e
passargli l'ordine di creare l'istanza dell'oggetto
 La creazione di un oggetto COM e l'inizializzazione
dell'istanza sono due fasi separate
Creazione di un Oggetto COM:
COM Library
 La COM Library necessita di un "Registro di Sistema" in cui
venga associato ad ogni CLSID il percorso del codice del
Server
 L'implementazione del "Registro di Sistema" dipende dal SO
 Windows NT utilizza il Registry
 In ogni caso il "Registro di Sistema" deve contenere:
 CLSID (key-entry)
 Tipo di server (in-process, local, remote)
 Percorso relativo alla DLL o EXE (percorso locale o
remoto)
 Il "Registro di Sistema" viene aggiornato ad ogni installazione
di una applicazione
Creazione di un Singolo Oggetto COM
In-Process e Locale
 Il Client invoca la funzione “CoCreateInstance” della COM
Library, passando:
 il CLSID (classe desiderata)
 l’IID (identificatore dell’interfaccia desiderata)
 Sulla base del CLSID ed utilizzando il "Registro di Sistema",
la COM Library:
 Localizza il Server in grado di istanziare la classe dell'oggetto
 Il Server viene attivato (se non lo è già)
 Il Server crea l'istanza dell’object class desiderata, passando
alla COM Library il puntatore all’interfaccia richiesta
 La COM Library passa questo puntatore al client
Creazione di un Singolo Oggetto COM
Remoto
 Il Client invoca la funzione “CoCreateInstance” della COM
Library, passando il CLSID e IID
 Sulla base del CLSID ed utilizzando il "Registro di Sistema",
la COM Library:
 localizza il Server (Remoto) in grado di istanziare la classe
dell'oggetto
 Viene contattato il Sistema Remoto per realizzare l'istanziazione (via
RPC)
 Il Sistema remoto controlla il suo Registro ed individua il server
 Il Server viene attivato (se già non lo è)
 Il Server crea l'istanza dell’object class desiderata, restituendo al
Sistema Remoto il puntatore all’interfaccia richiesta
 Il puntatore viene consegnato al client via RPC
Creazione di Oggetti Multipli
Class Factories
 Se l’utente deve creare una sola istanza di un oggetto,
allora la CoCreateInstance è sufficiente
 Molto spesso capita che l’utente necessita di istanze
multiple di oggetti della stessa classe
 In tal caso viene utilizzato l’oggetto COM “Class
Factory”
 Il Class Factory è un oggetto COM in grado di creare più
oggetti COM appartenenti ad una specifica classe
 Il nome non è molto appropriato, perché vengono creati
oggetti non classi
Creazione di Oggetti Multipli
Class Factories
 L'oggetto "Class Factory" viene gestito come un qualunque altro
oggetto COM (accesso tramite interfacce) e deve possedere almeno
l’interfaccia IClassFactory
 In realtà la CoCreateInstance si basa sull'oggetto Class Factory e
sull'interfaccia IClassFactory, ma ciò viene del tutto mascherato
all'utente
Class
Factory
Client
IClassFactory
:: CreateInstance()
:: LockServer()
Server
Creazione di Oggetti Multipli
Class Factories
 L’interfaccia IClassFactory contiene due metodi:
 CreateInstance. Crea una nuova istanza della classe di
oggetto che la Class Factory può istanziare.
 LockServer.
 Per attivare un oggetto Class Factory, il client invoca la
funzione della COM Library: CoGetClassObject
 Specifica il CLSID della classe di oggetti che l’oggetto
Class Factory dovrà istanziare
 Specifica l’IID dell’interfaccia per l’accesso a Class
Factory (IClassFactory)
 La COM Library crea l'oggetto Class Factory della classe
desiderata e fornisce al Client il puntatore richiesto
(IClassFactory)
Creazione di Oggetti Multipli
Class Factories
 Il Client ha già invocato la funzione CoGetClassObject e la COM Library ha fatto
partire la Class Factory e ha fornito al Client il puntatore ad una sua interfaccia
(ad esempio IClassFactory)
4. Il Client può invocare i
metodi dell'oggetto
A
Object
3.Puntatore interfaccia A
2
Class
Factory
Client
IClassFactory
1.IClassFactory::CreateInstance(IID_A)
Server
Inizializzazione di un Oggetto COM
 Quando un oggetto COM viene creato, esso ha dati
non inizializzati
 Il Client potrebbe aver di bisogno l’inizializzazione
di dati (ad esempio salvati sul disco)
 E' ovviamente necessario che i dati siano salvati in modo
persistente
 In tal caso, la prima interfaccia che il Client chiederà
è quella contenente le funzioni di inizializzazione
dell’oggetto.
 Esistono interfacce standard a tale scopo (utilizzo di
dati salvati in files):
 IPersistFile, IPersistStorage, IPersistStream
Distruzione di un Oggetto COM
 La soluzione più ovvia: il client che ha creato un
oggetto lo distrugge. Ciò non è possibile !
 Spesso un client passa il puntatore all’interfaccia di un
oggetto ad un altro client (che può fare lo stesso con altri
client)
 Ogni client non sa quanti altri client stanno utilizzando lo
stesso oggetto
 Solo l’oggetto può sapere quando nessun client lo
utilizza più
 Vengono utilizzati i metodi dell'interfaccia
IUnknown:
 IUnknown::AddRef()
 IUnknown::Release() basati sul Reference Counting
Distruzione di un Oggetto COM
Reference Counting
 Ogni oggetto COM che viene creato, mantiene un Reference
Count
 Quando l’oggetto COM passa il puntatore ad una sua
interfaccia ad un client, incrementa di 1 il Reference Count
 Quando un client termina l'utilizzo l'oggetto, deve invocare il
metodo IUnknown::Release(), che decrementa di 1 il
Reference Count
 Quando un client riceve il puntatore da un altro client, invoca
il metodo IUnknown::AddRef(), che incrementa di 1 il
Reference Count
 Se il Reference Count è 0, l’oggetto distrugge se stesso
 Problemi con i client che non rispettano la regola del
Reference Counting
Riuso di Componenti COM
 Containment
IUnknown
Client
A
IUnknown
B
Outer Object
Inner Object
IUnknown
 Aggregation
A
Client
Outer Object
IUnknown
Inner
B
Object
Marshalling
 Per invocare un metodo di un oggetto COM, il client
deve possedere il puntatore all’interfaccia relativa al
metodo (vtable)
 Il puntatore è un indirizzo di memoria
 Per poter essere utilizzato, lo spazio degli indirizzi
deve essere lo stesso di quello del client
 Come viene utilizzato il puntatore nell’architettura
COM ?
 La risposta dipende dalla tipologia del server: inprocess, local e remote
Marshaling: In-process server
 E' il caso più semplice.
 Lo spazio di indirizzamento del client e del server è lo stesso
 Il puntatore all’interfaccia può subito essere utilizzato per
accedere al binario del metodo richiesto
 Il Passaggio dei parametri e i valori di ritorno è realizzato nel
modo tradizionale
Client
COM Object
In-process server
Client process
Marshaling:Local Server
 Se il client e l'oggetto COM risiedono nella stessa
macchina, ma sono processi separati (spazio di
indirizzi diversi), il client non può puntare
all'interfaccia dell'oggetto
 Si utilizzano due oggetti COM:
Proxy e Stub
 Un proxy è un oggetto COM, che presenta la stessa
interfaccia dell’oggetto desiderato
 Il client invoca il codice del proxy, che crea un
package dei parametri del client e li invia tramite una
interprocess communication (dipende dal SO)
Marshaling:Local Server
 La richiesta arriva ad un altro oggetto COM: Stub
 Lo stub unpackage la richiesta e passa i parametri del
client all’oggetto reale
 Ogni risposta da parte dell’oggetto viene inviata nello
stesso modo al client
Single Machine
Client
Proxy
Interprocess
Stub
Object
communication
Client process
Server process
Marshaling: Remote Server
 Stesso schema del Local Server
 La comunicazione è basata su DCOM, utilizzando
RPC
Machine Y
Machine X
Client
Proxy
Client process
RPC
Stub
Object
Server process
Marshaling
 Cosa è il Marshaling ?
 Necessità di un formato standard per lo scambio di
parametri e risultati tra Proxy e Stub (soprattutto per i
remote server) e di opportuno codice per eseguire le
appropriate conversioni
 Macchine diverse possono
rappresentazioni di dati diverse
usare
codifiche
e
Scarica

Architettura COM/DCOM