Lucidi_3
Document Sample


Obiettivo della tesi
Progettazione e sviluppo di uno strumento per integrare fra di loro
i Software Components sviluppati in COM e CORBA, le due
principali architetture ad oggetti presenti attualmente sul mercato.
COM è la piattaforma sviluppata dalla Microsoft.
CORBA è stata sviluppata dall’OMG GROUP.
1
Evoluzione del Software
Nel corso degli anni sono state sviluppate diverse tecniche e
metodologie per affrontare e semplificare lo spinoso problema
dello sviluppo del software. Ad esempio:
programmazione strutturata,
modularizzazione,
strutture dati astratte,
programmazione ad oggetti.
Quest’ultima ha ancora dei limiti:
richiede che tutto il codice sia scritto nello stesso linguaggio di
programmazione,
richiede compatibilità binaria,
non supporta applicazioni distribuite,
non fornisce un ambiente di composizione.
2
Evoluzione delle applicazioni
In passato le applicazioni erano monolitiche e dovevano essere
compilate e linkate insieme.
Applicazione monolitica
La tendenza attuale è quella di suddividere le applicazioni in
moduli o componenti.
Applicazione a componenti
3
Principali vantaggi della suddivisione
Sostituzione di singoli componenti senza ricompilare tutto.
Un componente migliorato sostituisce uno vecchio, senza la
necessità di modificare il resto dell’applicazione.
Funzionamento in rete.
RETE
Componenti situati su macchine remote che vengono gestiti
trasparentemente.
4
Requisiti dei componenti
Collegamento dinamico
Si spinge il processo di divisione dei componenti ad un punto
tale da poter collegare o sostituire un componente a tempo di
esecuzione.
Incapsulamento
Si cerca di nascondere i dettagli dell’implementazione. Si deve
isolare il più possibile il client dal componente in modo tale da
avere:
1. Indipendenza dal linguaggio di programmazione.
2. Componenti forniti in formato binario.
3. Compatibilità verso il basso. Nuove versioni di un
componente devono essere compatibili con le versioni
precedenti.
4. Indipendenza dalla locazione. Un componente deve essere
gestito in modo trasparente, indipendentemente dal fatto che
sia locale o remoto.
5
L’interfaccia
Abbiamo visto che il client e il server devono essere divisi;
l’unica cosa che hanno in comune è l’interfaccia.
Siccome dobbiamo avere indipendenza dal linguaggio di
programmazione, l’interfaccia è definita con un linguaggio creato
appositamente.
Nel caso di COM abbiamo il MIDL (Microsoft Interface
Definition Language).
Nel caso di CORBA abbiamo l’OMG IDL (Object
Menagement Group Interface Definition Language).
6
Creazione di un componente
Vediamo il processo per la creazione di un componente, sia per
COM che per CORBA, senza considerare i dettagli.
1
Definizione delle
interfacce in IDL
2
Preprocessore
IDL
3 4
Classe di base astratta Codice di marshaling per i parametri
che rappresenta
l’interfaccia
Client Server
proxy (COM) stub (COM)
stub (CORBA) skeleton (CORBA)
6
5
Client Derivazione e
implementazione
della classe astratta
6
Componente
7
Esempio in COM
// MIDL
// intestazione dell’interfaccia
[
object,
uuid(4ECECC21-D25E-11D2-8B40-00400559C94F),
pointer_default(unique)
]
interface IAccount : IUnknown
{
// metodi
HRESULT deposit([in] long amount);
HRESULT withdraw([in] long amount);
// attributi
[propget] HRESULT balance([out, retval]
long * pRetVal);
[propget] HRESULT balance([in] long NewVal);
};
Questo file viene processato dal compilatore MIDL.
8
Codice C++ prodotto dal compilatore MIDL
class IAccount : public IUnknown
{
...
public:
virtual HRESULT STDMETHODCALLTYPE
deposit(long amount) = 0;
virtual HRESULT STDMETHODCALLTYPE
withdraw(long amount) = 0;
virtual HRESULT STDMETHODCALLTYPE
put_balance(long NewVal) = 0;
virtual HRESULT STDMETHODCALLTYPE
get_balance(long *pRetVal) = 0;
...
};
9
Implementazione in COM
class CAccount : public IAccount
{
private:
// reference count
// tiene traccia dei client attivi
ULONG m_refCnt;
// variabile membro che memorizza il saldo
LONG m_balance;
...
public:
CAccount();
virtual ~CAccount();
// IUnknown
STDMETHODIMP QueryInterface(REFIID, void **);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IAccount
STDMETHODIMP deposit(long amount);
STDMETHODIMP withdraw(long amount);
STDMETHODIMP put_balance(long NewVal);
STDMETHODIMP get_balance(long *pRetVal);
...
};
10
ClassFactory
Tutti gli oggetti COM vengono creati in modo standard da una
particolare classe: la ClassFactory.
La sua interfaccia è:
interface IClassFactory : IUnknown
{
HRESULT CreateInstance(IUnknown *pUnkOuter,
REFIID iid, void **ppv);
HRESULT LockServer(BOOL fLock);
};
Come si crea un oggetto:
Usando la Class Factory direttamente:
IClassFactory *pCF = ...; // CoGetClassObject
HRESULT hr = pCF->CreateInstance(pUnkOuter,
riid, (void **) ppvObj);
pCF->Release();
Usando la funzione CoCreateInstance:
HRESULT hr = CoCreateInstance(rclsid, pUnkOuter,
CLSCTX_ALL, riid, (void **) ppvObj);
11
Processo per la creazione di un componente
COM di tipo InProc (DLL)
componente.idl
componente.h
componente_p.c
MIDL.EXE
componente_i.c
dlldata.c
compilatore
e linker
makefile
componente.dll
componente.def
componente_impl.cpp
Registrazione
nel registro di
Windows
12
Esempio in CORBA
// OMG IDL
interface Account
{
attribute long balance;
void deposit(in long amount);
void withdraw(in long amount);
};
Questo codice viene processato dal compilatore IDL.
13
Codice C++ prodotto dal compilatore IDL
class Account : virtual public CORBA::Object
{
public:
virtual ~Account();
...
// codice per l’attributo
virtual CORBA::Long balance() = 0;
virtual void balance(CORBA::Long value) = 0;
// metodi dell’interfaccia
virtual void deposit(CORBA::Ulong amount) = 0;
virtual void withdraw(CORBA::Ulong amount) = 0;
...
};
Classi per lo stub e lo skeleton
// stub per il client
// è una classe istanziabile
// i metodi dell’interfaccia Account vengono
// implementati con il codice per la chiamata remota
class Account_stub : virtual public Account
{
...
};
// skeleton per il server
// non è istanziabile perché si devono
// implementare i metodi dell’interfaccia Account
class Account_skel:
virtual public StaticMethodDispatcher,
virtual public Account
{
...
};
14
Implementazione in CORBA
class Account_impl : virtual public Account_skel
{
private:
CORBA::Long _current_balance;
...
public:
// codice per l’attributo
CORBA::Long balance();
void balance(CORBA::Long value);
// codice per i metodi
void deposit(CORBA::Long amount);
void withdraw(CORBA::Long amount);
...
};
Si devono ovviamente implementare questi metodi.
15
Processo per la creazione di un componente
CORBA di tipo Library (modulo)
componente.idl
Compilatore IDL
componente.h componente.cpp
componente_impl.cpp makefile
Compilatore e linker
Registrazione
componente.so nella
Implementation
Repository
16
Integrazione dei due sistemi
Architettura per far interagire i due sistemi:
Client COM View Server CORBA
Server COM
Client CORBA
Passaggio dei dati tra
COM e CORBA
La View in particolare:
COM CORBA
Riferimento all’oggetto in Implementazione
COM dell’oggetto in CORBA
Bridge
View in COM Riferimento all’oggetto
dell’oggetto CORBA in CORBA
Al livello della View avviene il passaggio dei dati tra CORBA e
COM, grazie al mapping tra OMG IDL e Microsoft IDL.
17
Esempio di codice della View
(Server COM / Client CORBA)
...
// Inizializzazione di CORBA
CORBA::ORB_var orb = ...;
CORBA::BOA_var boa = ...;
...
class CAccount : public IAccount
{
private:
...
// riferimento all’oggetto CORBA
Account_var pAccCORBA;
...
};
// Implementazione del costruttore
CAccount::CAccount()
{
...
// inizializzazione dell’oggetto CORBA
CORBA::Object_var obj;
obj = orb->bind(“IDL:Account:1.0”);
pAccCORBA = Account::_narrow(obj);
...
}
// Implementazione del metodo deposit
HRESULT STDMETHODCALLTYPE
CAccount::deposit(long amount)
{
// reindirizzamento al metodo dell’oggetto CORBA
pAccCORBA->deposit(amount);
return S_OK;
}
18
Riassumendo:
Processo per l’integrazione dei due sistemi
Obiettivo della
tesi
OMG IDL
MIDL
View
Client COM
Server COM
Client CORBA Server CORBA
19
Il traduttore
Il traduttore è stato realizzato modificando il compilatore IDL
della distribuzione Mico di CORBA, in modo tale da fargli
produrre codice MIDL.
Uso del traduttore:
idl -–codegen-midl <nome file.idl>
Si ottiene in output il file <nome file.midl> che contiene la
traduzione in MIDL.
Tipi di dato che il traduttore è in grado di mappare:
Tipi di base
Costanti
Enumerati
Stringhe
Strutture
Unioni
Sequenze
Array
Operazioni (anche quelle oneway)
Attributi
Interfacce
Non è in grado di tradurre i nuovi tipi introdotti con la specifica
2.2 di CORBA dato che non è stata prevista nessuna traduzione
ufficiale. Questi sono:
Native
Value
ValueBox
ValueMember
20
Esempio di traduzione da OMG IDL a MIDL
// OMG IDL
module MyModule
{
interface Base1
{
void func1(in long value);
};
interface Base2
{
long func2();
};
interface Derived : Base1, Base2
{
attribute long amount;
};
};
21
Esempio di traduzione da OMG IDL a MIDL
// MIDL
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(C4965500-7A82-11D3-8B40-00400559C94F),
pointer_default(unique)
]
interface IMyModule_Base1 : IUnknown
{
HRESULT func1( [in] long value );
};
[
object,
uuid(C4965501-7A82-11D3-8B40-00400559C94F),
pointer_default(unique)
]
interface IMyModule_Base2 : IUnknown
{
HRESULT func2([out, retval] long *pRetVal);
};
[
object,
uuid(C4965502-7A82-11D3-8B40-00400559C94F),
pointer_default(unique)
]
interface IMyModule_Derived : IUnknown
{
[propget] HRESULT amount([out, retval]
long *pRetVal);
[propput] HRESULT amount([in] long NewVal);
};
[
uuid(C4965503-7A82-11D3-8B40-00400559C94F),
version(1.0),
helpstring("derive 1.0 Type Library")
]
library deriveLib
{
22
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(C4965504-7A82-11D3-8B40-00400559C94F),
helpstring("MyModule_Base1 Class")
]
coclass MyModule_Base1
{
[default] interface IMyModule_Base1;
};
[
uuid(C4965505-7A82-11D3-8B40-00400559C94F),
helpstring("MyModule_Base2 Class")
]
coclass MyModule_Base2
{
[default] interface IMyModule_Base2;
};
[
uuid(C4965506-7A82-11D3-8B40-00400559C94F),
helpstring("MyModule_Derived Class")
]
coclass MyModule_Derived
{
[default] interface IMyModule_Derived;
interface IMyModule_Base1;
interface IMyModule_Base2;
};
};
23
Riconoscimenti ottenuti
Il traduttore è stato apprezzato dagli stessi autori di Mico che lo
hanno incluso nella distribuzione ufficiale (per maggiori
approfondimenti è possibile consultare il sito www.mico.org).
È stata una soddisfazione personale vedere il mio nome apparire
insieme agli autori di MICO.
Estratto dal sito di Mico:
Authors
The CORBA core was implemented by:
Kay Römer: ORB, IIOP, OBV.
Arno Puder: IDL-compiler, Interface Repository.
Frank Pilhofer: POA, OBV.
With a little help from some friends:
Kai-Uwe Sattler: Naming and event service.
Lars Doelle: Qt support.
Owen Taylor: GTK support.
Elliot Lee: C language mapping. (note: removed in MICO 2.2.7)
Christian Becker: Stream service.
Ben Eng, Andrew Metcalfe, Christoph Best, and Andreas Schultz:
adopted MICO to various C++ compilers.
Martin Sander, Rudolf Janz: adopted MICO to Visual-C++.
Marcus Müller: Codeset converters.
Karel Gardas: Relationship service.
Leif Jakobsmeier: Property service.
Torben Weis: Trading service.
Jacques Tremblay: FLtk support.
Wil Evers: CORBA compliant exception handling.
Massimo Di Giorgio: Microsoft IDL generator.
Carsten Zerbst: Time Service.
24
Get documents about "