A partire da giugno 2000, Microsoft ha iniziato a dare le prime indicazioni su uno tra i più importanti progetti futuri: l’ambiziosa piattaforma.Net. “DotNet” dovrebbe portare, secondo i piani dell’azienda di Redmond, ad una soluzione indipendente dalla piattaforma. Si tratta di una sfida importante, anche perché per la prima volta Microsoft cerca di collocare una propria soluzione in maniera trasversale rispetto ai sistemi operativi e agli ambienti di sviluppo, siano suoi o dei concorrenti.
La nuova piattaforma è composta da diversi elementi, ciascuno dotato di una propria autonomia, ma che trova la completa efficienza soltanto dalla sinergia con gli altri elementi costitutivi della piattaforma.
Il CLR
Il cuore di tutta l’architettura è il CLR (Common Language Runtime).
Il CLR (figura 1) è una macchina virtuale che astrae il sistema operativo sottostante e che ha i seguenti compiti:
- eseguire il software scritto ad hoc per il runtime
- gestire i servizi di start e stop di thread e processi
- gestire autonomamente l’allocazione e la liberazione della memoria
- gestire il Garbage Collecting, cioè il recupero di zone di memoria allocate per oggetti che non sono più referenziati
La vera svolta sta nel fatto che, essendo un ambiente di runtime, garantisce l’indipendenza dal sistema operativo e, di conseguenza, dalla piattaforma hardware. Questo farà si che, se all’inizio esisterà un CLR soltanto per i sistemi Microsoft, nulla impedirà lo sviluppo di CLR per sistemi operativi diversi, Linux in primis.
Di conseguenza, esattamente come accade per il codice Java, il codice prodotto per la piattaforma.Net sarà compatibile con tutti i CLR esistenti, quindi sarà possibile far girare la stessa applicazione su sistemi operativi diversi e su piattaforme diverse, a condizione che su queste sia installato l’apposito CLR (figura 2).
La fase di esecuzione
Quando il CLR esegue un’applicazione.Net compie una serie di operazioni in sequenza:
- Carica in memoria il codice pseudo-compilato, questo perché i compilatori.Net non producono codice nativo per una certa piattaforma hardware/software, ma un codice intermedio chiamato IL (Intermediate Language), che sarà poi definitivamente compilato dal CLR in fase di esecuzione.
- Verifica che il codice sia conforme alle specifiche sui tipi di dati permessi (Type-Safe)
- Compila il codice IL in codice nativo per la piattaforma ospite. Il codice viene ottimizzato per il sistema operativo in esecuzione, ma anche per l’hardware specifico.
Se, infatti, la macchina sulla quale viene compilato il codice IL è dotata di un processore recente, il codice nativo generato potrà utilizzare istruzioni più avanzate rispetto al codice prodotto su una macchina dotata di processore più vecchio.
La compilazione inoltre non comprende tutto il codice dell’applicazione, ma soltanto i metodi fino a quel momento utilizzati. Questo garantisce buone prestazioni anche alla prima esecuzione di applicazioni complesse.
Questo tipo di compilazione è chiamata JIT (Just In Time) e si basa fondamentalmente su 3 principi: -
- in fase di avvio dell’applicazione si compilano solo le parti di codice necessarie per la fase di start dell’applicazione stessa
- se durante la fase di run, l’applicazione richiede porzioni di codice che non sono ancora state compilate, la compilazione viene eseguita sul momento (Just In Time, appunto).
- la volta successiva che verrà eseguita l’applicazione il codice IL sarà già in parte compilato in codice nativo, quindi avrò un considerevole vantaggio in termini di prestazioni.
La fase di compilazione può anche essere effettuata in maniere esaustiva durante il setup dell’applicazione, in modo da avere subito a disposizione tutto il codice già compilato per la piattaforma ospite.
- Esegue il codice nativo (sia esso compilato JIT oppure precompilato durante il setup).
Durante l’esecuzione il CLR si occupa di gestire lo start e lo stop dei processi, il garbage collecting e la sicurezza.
Scrivere software per.Net
Dopo aver visto come viene eseguita un’applicazione.Net all’interno del CLR, possiamo chiederci come si faccia a scrivere del codice e a farlo girare su una qualche piattaforma dotata di CLR. Per far questo ci serve il .Net Framework SDK, un framework, appunto, contenente i compilatori che generano il codice IL.
La filosofia di scrittura del codice è comune a quella di Java ed è una vecchia conoscenza per chi era abituato a sviluppare in C e Pascal sul caro e vecchio MS-DOS, oppure per chi utilizza il JDK per scrivere applicazioni Java. I passi sono sempre i soliti:
- Scrittura del codice sorgente utilizzando un qualsiasi linguaggio di programmazione tra quelli supportati (cioè tra quelli per cui è presente un compilatore).
- Compilazione in IL del componente o dell’applicazione.
- Copia dei files sulla macchina di destinazione.
- Esecuzione
Il punto di forza di questa architettura di sviluppo è che virtualmente è possibile ascrivere un’applicazione.Net in qualsiasi linguaggio di programmazione, a condizione che esista il compilatore che traduca il codice sorgente in IL.
Ma non è tutto, poiché le specifiche per la costruzione dei compilatori sono aperte, è un’ipotesi tutt’altro che remota la possibilità di scrivere codice.Net in linguaggi non convenzionali per il mondo Microsoft, quali ad esempio il Pascal, il Fortran o il Cobol.
Le specifiche inoltre sono molto rigorose e richiedono che il linguaggio sia conforme ad una serie di vincoli forti, quali ad esempio:
- la filosofia fortemente object-oriented
- la tipizzazione forte
- la compatibilità con il CTS (Common Type System), cioè un insieme di tipi predefinito a cui i linguaggi si devono adattare
- l’utilizzo della BCL (Base Class Library), cioè una completa libreria di classi che è possibile utilizzare da qualsiasi linguaggio di programmazione compatibile con le specifiche.
L’esistenza di questi vincoli forti permette di scrivere un’applicazione.Net utilizzando differenti linguaggi di programmazione, poiché si è certi che ogni linguaggio utilizzato impiegherà gli stessi tipi e la stessa libreria di classi. I linguaggi attualmente supportati sono:
- Visual Basic.Net (un’evoluzione di Visual Basic che lo rende conforme ai vincoli precedenti)
- Visual C++.Net (come sopra)
- C# (il nuovo linguaggio nato con la piattaforma.Net, di cui parleremo più approfonditamente in articoli successivi)
La figura 3 sintetizza tutto ciò che è stato detto, ora non resta altro da fare che mettersi al lavoro e provare questa nuova architettura, che si preannuncia davvero interessante.