Mono, un progetto maturo, d'aiuto anche in progetti complessi, da seguire con interesse

Creato il 22 agosto 2010 da Hugor @msdiaz61

Mono riunisce molti degli aspetti che si possono trovare in un moderno linguaggio di programmazione orientato agli oggetti. Uno dei vantaggi principali è il fatto che il codice sorgente viene compilato in un linguaggio intermedio noto come CLI (Linguaggio Comune Intermedio) ed eseguito all'interno di un ambiente controllato.
Il codice così eseguito prende il nome di Codice Gestito. L'esecuzione di codice gestito offre vari vantaggi, molti dei quali saranno già noti a chi programma in Java o in linguaggi di scripting.

  • Meno Errori. In ambienti a compilazione tradizionale è facile che errori di programmazione blocchino in modo inatteso l'esecuzione del programma. Tali errori sono spesso dovuti ad un'errata gestione della memoria, quali la mancata deallocazione di risorse, l'accesso oltre i limiti di un vettore o l'uso di un puntatore nullo. In mono la gestione delle eccezioni e l'esecuzione in modalità gestita evita la comparsa di errori di questo tipo.

  • Garbage Collection. L'esecuzione runtime delle applicazioni ha il pieno supporto alla gestione automatica della memoria. Gli oggetti allocati e non più utilizzati vengono automaticamente distrutti, evitando al programmatore l'aggiunta di distruttori e di codice di deallocazione della memoria.

  • Sicurezza. Tramite la creazione di modelli di dominio e un esteso gruppo di attributi, è possibile specificare tutti i vincoli di permessi necessari a un'applicazione. Ogni programma può specificare i permessi che gli sono necessari e gestire le eventuali eccezioni di sicurezza sollevate in caso di mancanza di autorizzazioni.

  • Nulla è perso. Qualora un'applicazione legacy richieda un accesso diretto all'hardware o l'esecuzione di codice migrato dai linguaggi C/C++, è possibile compilare codice in modalità unsafe e utilizzare i costrutti specifici della programmazione non gestita (uso di puntatori, di riferimenti, gestione manuale della memoria etc).

Mono facilita anche il riuso di codice esistente tutelando eventuali investimenti pregressi. L'infrastruttura P/Invoke permette infatti l'accesso a tutti i metodi inclusi in librerie dinamiche (dll) esistenti, con poche righe di codice e in modo abbastanza elementare.

Il maggior vantaggio di Mono è però la riduzione dei tempi di sviluppo software. C#, ad esempio, ha una curva di apprendimento ridotta per i programmatori che vengono dal mondo C/C++ o Java, in quanto condivide con tali linguaggi terminologia OOP e sintassi. In più aggiunge alcune funzionalità che riducono sensibilmente i tempi di sviluppo: l'uso di Delegati ed Eventi, di Proprietà ed Interfacce sono solo alcuni esempi.

Contrariamente a quanto si può pensare, infine, l'esecuzione di codice CIL all'interno della macchina virtuale mono non è affatto lenta. Mono utilizza un JIT (un compilatore just in time) per tradurre il linguaggio bytecode intermedio in codice macchina. L'evoluzione del jitter e il suo continuo sviluppo ne garantiscono prestazioni simili se non superiori a quello utilizzato per la compilazione Java.

Più piattaforme e più linguaggi.

La vera forza di Mono è però la libertà che offre, sia in termini di linguaggi che di architetture. Contrariamente a quanto avviene per la piattaforma .net di Microsoft, Mono supporta Windows, Linux, Mac OS X e differenti architetture hardware tra cui x86, PowerPC e SPARC. Inoltre, le librerie Mono (quali ad esempio gtk#) sono disponibili per tutte queste architetture, e permettono una reale programmazione multi-piattaforma.

Il runtime comune di Mono (ed il meccanismo di traduzione just in time) permette anche di svincolare il programmatore dal linguaggio. Si può sviluppare pressoché in qualunque linguaggio, da C# a VB, da Java a Python, Fortran, Lisp e Cobol. I linguaggi supportati sono veramente moltissimi (si veda ad esempio http://www.dotnetpowered.com/languages.aspx).

Alcuni strumenti.

Mono contiene un discreto numero di strumenti a riga comando che permettono la compilazione e l'esecuzione di codice gestito, oltre che facilitare l'apprendimento del linguaggio C#.

Mcs.

mcs è il compilatore C# di mono. Il comando permette di compilare il codice, di includere risorse e collegare librerie di funzioni. Il risultato della compilazione è tipicamente un Assembly (una dll o un exe).

Mono.

mono è il comando che permette di eseguire un programma all'interno della macchina virtuale. mono utilizza il Jitter per tradurre il codice IL in codice nativo ed eseguirlo. Di seguito viene illustrato il risultato di mono --version, per il comando mono utilizzato di seguito per alcuni piccoli esempi.

$ mono --version
Mono JIT compiler version 1.9.1 (tarball)
Copyright (C) 2002-2007 Novell, Inc and Contributors. www.mono-project.com
TLS: __thread
GC: Included Boehm (with typed GC)
SIGSEGV: altstack
Notifications: epoll
Architecture: x86
Disabled: non

monodoc.

Si tratta del visualizzatore di documentazione incluso con il progetto Mono. Permette di sfogliare la documentazione inclusa con le librerie ufficiali del progetto e di studiare i fondamenti del linguaggio C#. Anche gli assembly installati da terze parti possono includere documentazione visibile da tale programma.

Figura 1: monodoc

Monop2.

Nel caso in cui non sia facile trovare documentazione sui metodi o la definizione di una struttura o di una classe, o qualora si sia interessati unicamente all'elenco di metodi e proprietà, può essere d'aiuto il comando monop2. Di seguito un esempio.

$ monop2 System.Int32
[Serializable]
public struct Int32 : IComparable, IComparable, IConvertible, IEquatable, IFormattable {
public static int Parse (string s);
public static int Parse (string s, IFormatProvider fp);
public static int Parse (string s, System.Globalization.NumberStyles style);
public static int Parse (string s, System.Globalization.NumberStyles style, IFormatProvider fp);
public static bool TryParse (string s, out int result);
public static bool TryParse (string s, System.Globalization.NumberStyles style, IFormatProvider provider, out int result);
public int CompareTo (int value);
public int CompareTo (object v);
public bool Equals (int value);
public override bool Equals (object o);
protected virtual void Finalize ();
public override int GetHashCode ();
public Type GetType ();
public TypeCode GetTypeCode ();
protected object MemberwiseClone ();
bool System.IConvertible.ToBoolean (IFormatProvider provider);
byte System.IConvertible.ToByte (IFormatProvider provider);
char System.IConvertible.ToChar (IFormatProvider provider);
DateTime System.IConvertible.ToDateTime (IFormatProvider provider);
decimal System.IConvertible.ToDecimal (IFormatProvider provider);
double System.IConvertible.ToDouble (IFormatProvider provider);
short System.IConvertible.ToInt16 (IFormatProvider provider);
int System.IConvertible.ToInt32 (IFormatProvider provider);
long System.IConvertible.ToInt64 (IFormatProvider provider);
sbyte System.IConvertible.ToSByte (IFormatProvider provider);
float System.IConvertible.ToSingle (IFormatProvider provider);
object System.IConvertible.ToType (Type conversionType, IFormatProvider provider);
ushort System.IConvertible.ToUInt16 (IFormatProvider provider);
uint System.IConvertible.ToUInt32 (IFormatProvider provider);
ulong System.IConvertible.ToUInt64 (IFormatProvider provider);
public override string ToString ();
public string ToString (IFormatProvider provider);
public string ToString (string format);
public string ToString (string format, IFormatProvider fp);
public const int MaxValue = 2147483647;
public const int MinValue = -2147483648;
}

Monodevelop.

È un'IDE avanzata per la programmazione con Mono. Sviluppata in gtk#, deriva dal noto SharpDevelop. monodevelop include parecchie funzionalità di un ambiente di sviluppo integrato avanzato: documentazione integrata, autocompletamento del codice, intellisense, supporto alla compilazione, gestione dei riferimenti (collegamenti ad assembly esterni e non solo).

Figura 2: monodevelop nuovo progetto

Figura 3: monodevelop IDE con intellisense

Utilizziamo gli strumenti offerti sino ad ora per compilare una semplice applicazione console. Il classico esempio iniziale per qualunque linguaggio di programmazione è ovviamente HelloWorld. Il programma non farà altro che stampare a terminale un saluto, eventualmente accettando un parametro con il nome dell'utente da salutare. Per farlo, creare un file HelloYou.cs e incollarvi il codice seguente:

using System;
public class EntryClass
{
public static void Main(string[] args)
{
if(args.Length != 1)
{
Console.WriteLine("Hello World!!");
return;
}
Console.WriteLine(String.Format("Hello {0}!!", args[0].ToUpper()));
}
}

Quindi lanciare i comandi per la compilazione e l'esecuzione del programma. Il compilatore utilizzato in questo caso è gmcs, il compilatore della versione 2.0 (mcs è quello per la versione 1.0).

$ gmcs HelloYou.cs
$ mono HelloYou.exe
Hello World!!
$ mono HelloYou.exe gabriele
Hello GABRIELE!!

Si può anche complicare il programma e dotarlo di una banalissima interfaccia grafica. In mono è stato aggiunto il supporto alle librerie System.Windows.Forms, che permettono l'uso di controlli e componenti in stile Windows. Si può ad esempio pensare di creare una piccola finestra, con una casella di testo ed un pulsante, che visualizzi un messaggio di saluto una volta inserito il nome e premuto il tasto.

using System;
using System.Windows.Forms;
public class MainClass
{
public static void Main()
{
Application.Run(new HelloForm());
}
}
public class HelloForm : Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox tbNome;
private System.Windows.Forms.Button btOk;
public HelloForm()
{
InitializeForm();
}
private void btOk_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello " + tbNome.Text);
}
private void InitializeForm()
{
this.label1 = new System.Windows.Forms.Label();
this.tbNome = new System.Windows.Forms.TextBox();
this.btOk = new System.Windows.Forms.Button();
this.SuspendLayout();
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(11, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(99, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Inserisci il tuo nome";
this.tbNome.Location = new System.Drawing.Point(12, 36);
this.tbNome.Name = "tbNome";
this.tbNome.Size = new System.Drawing.Size(259, 20);
this.tbNome.TabIndex = 1;

this.btOk.Location = new System.Drawing.Point(14, 75);
this.btOk.Name = "btOk";
this.btOk.Size = new System.Drawing.Size(75, 23);
this.btOk.TabIndex = 2;
this.btOk.Text = "Ok";
this.btOk.Click += new System.EventHandler(this.btOk_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 105);
this.Controls.Add(this.btOk);
this.Controls.Add(this.tbNome);
this.Controls.Add(this.label1);
this.Name = "HelloForm";
this.Text = "HelloYou";
this.ResumeLayout(false);
this.PerformLayout();
}
}

Si osservi come venga facilmente aggiunto l'evento di pressione del tasto: è sufficiente utilizzare l'operatore += per aggiungere un delegato che si occupi della gestione dell'evento OnClick del pulsante. Per compilare il programma è necessario includere l'opzione -pkg:dotnet affinché venga gestito correttamente il riferimento alle librerie windows forms del framework 2.0.

$ gmcs HelloWin.cs -pkg:dotnet
$ mono HelloWin.exe

Di seguito una immagine del programma in esecuzione.

Figura 4: hellowin

Infine, visto che precedentemente è stato citato gtk#, vediamo anche un piccolo esempio con un'interfaccia diversa. In questo caso nella finestra principale appare un solo pulsante, premuto il quale il saluto viene visualizzato sulla console. Di seguito viene riportato il codice del programma e un'immagine illustrativa del suo funzionamento.

using System;
using Gtk;
public class MainClass
{
public static void Main (string[ ] args)
{
Application.Init( );
Window w = new Window ("Hello Gtk");
Button b = new Button ("Ok");
b.Clicked += new EventHandler (Button_Clicked);
w.Add (b);
w.SetDefaultSize (200, 100);
w.ShowAll();
Application.Run ( );
}
static void Button_Clicked (object o, EventArgs args)
{
System.Console.WriteLine ("Hello, World!");
}
}

Si compila il programma, dando il riferimento alle librerie gtk#.

$ gmcs HelloGtk.cs -pkg:gtk-sharp-2.0
$ mono HelloGtk.exe

Ed ecco il risultato.

Figura 5: hellogtk

Conclusioni.

Con la versione 2.0 Mono ha incluso il supporto a un notevole numero di librerie ed effettuato molti miglioramenti rispetto alla versione precedente. Si comincia dalle API con compatibilità Microsoft, come ADO.NET 2.0 (accesso ai database) e ASP.NET 2.0 (sviluppo di pagine web e webservice), Windows.Forms 2.0 per la creazione di applicazioni desktop, e si prosegue con una versione rivista di System.Core che fornisce il supporto per Language Integrated Query (LINQ).

A seguire, le API Mono, che vanno da GTK# 2.12 per la creazione di applicazioni desktop su Linux, Windows e Mac OS X, a Mono.Cecil per la manipolazione di file in formato nativo ECMA CLI, a Mono.Cairo e l'API grafica 2D per il rendering in svariate forme, compresi i formati postscript e PDF, il supporto SQLite e Mono.Posix, una libreria per l'accesso a funzionalità specifiche di Linux e UNIX dall'applicazione managed.

Si cominciano a trovare in rete parecchi progetti che fanno uso della piattaforma di programmazione Mono per lo sviluppo: dal motore di SecondLife, completamente riscritto, a progetti quali Banshee Media Player, F-Spot Photo Manager, o TomBoy Notes.

Mono è un progetto maturo, e può essere d'aiuto anche in progetti complessi. L'uso di webservice e di tecniche di programmazione distribuita permettono anche di creare applicazioni web o smartclient di alto impatto e usabilità. Un progetto da seguire con interesse.

fonte: Pluto Journal


Se ti è piaciuto l'articolo , iscriviti al feed cliccando sull'immagine sottostante per tenerti sempre aggiornato sui nuovi contenuti del blog:


Potrebbero interessarti anche :

Possono interessarti anche questi articoli :