VorwortMan kann über Microsoft sagen, was man will, aber eines muss ich ihnen schon lassen: mit Produkten wie SQL-Server, Visual Studio und .NET ist ihnen ein großer Wurf gelungen, mit denen im Bereich der Softwareentwicklung sinnvolle Standards in Bezug auf objektorientiertes Programmieren gesetzt wurden. Eine Trennung zwischen Benutzeroberfläche und Programmlogik war mit den Win32-IDEs (z.B. Visual Basic 6) zwar möglich, aber verhältnismäßig kryptisch und recht umständlich gelöst. In .NET wird man fast schon gezwungen, sich einen sauberen Programmierstil anzueignen. Nun gibt es endlich für die unterschiedlichsten Projekttypen einheitliche Vorgehensweisen. Der kleine Haken dabei ist jedoch, dass das .NET-Framework ausschließlich auf Windows-Plattformen betrieben wird, trotz der gelobten Plattformunabhängigkeit seitens Microsoft.
Wie gut, dass es Entwickler gibt, die sich diesen Umstand zu Herzen genommen und das mono-Projekt ins Leben gerufen haben. mono ist ein Nachbau des .NET-Frameworks und läuft neben Windows auch auf Linux und Mac OS X. Ich wollte wissen, wie gut das funktioniert, ob man wirklich, wie es versprochen wird, seine Visual Studio-Anwendungen ohne Abstriche auf Mac portieren kann und was es zu beachten gibt.
UmgebungIn meinem Fall betreibe ich mono unter Mac OS X 10.6.4. Das .NET-Projekt wurde in Visual Studio 2005 geschrieben. Dabei handelt es sich um eine einfache Windows Forms-Anwendung, die ein SQL-Frontend für Microsoft SQL Server darstellt, sprich: man gibt eine SQL-Abfrage ein und bekommt das Ergebnis in einem DataGrid angezeigt. Soweit nichts Spektakuläres.
VorbereitungZunächst einmal wird das mono-Framework benötigt. Dieses kann man sich frei unter
herunterladen. Das mono-Framework ist übrigens OpenSources, weswegen Interessierte auch gleich die Quelltexte laden können.
Gut, die Installation des Frameworks ist dank eines automatischen Installers keine Raketentechnik und geht in der Regel problemlos vonstatten. Was wir nun aber noch benötigen, ist eine Entwicklungsumgebung. Das Pendant zu Visual Studio nennt sich MonoDevelop und ist, je nach Plattform, in einem unterschiedlichen Entwicklungsstadium. Die Mac OS X-Version hat beispielsweise keinen GUI Designer, da Drap & Drop noch nicht implementiert werden konnte. So bleibt nur das Codieren der Positionen, das Pixelzählen und immer wieder Ausprobieren. MonoDevelop ist unter der oben genannten Seite verfügbar. Auch hier ist die Installation einfach und nach wenigen Sekunden hat man ein Disk Image, wo man nur das MonoDevelop-Icon in die Programme ziehen muss.
StartNach dem Start von MonoDevelop erhält man eine Startseite, die stark an Visual Studio erinnert. Hier werden die zuletzt benutzten Projekte sowie Neuigkeiten und Links zu verwandten Seiten angezeigt.
MonoDevelop StartseiteDie MonoDevelop-Oberfläche ist alles andere als nativ. Sie verhält sich nicht mac-like und sieht auch nicht so aus.
In MonoDevelop wird nach Projekten und Projektmappen gegliedert, was es für Ein- und Umsteiger leichter macht, seine Projekte wiederzufinden. Ich lade also mein SQLer-Projekt (sln-Datei, bekannt aus Visual Studio) in die IDE. Alle bekannten Dateitypen werden in der nicht-nativen Auswahlbox aufgeführt.
Nach dem Öffnen der Projektmappe befindet man sich im SourceCode. Wie schon anfangs erwähnt, findet man keinen GUI Designer, mit dem man die Oberfläche bearbeiten könnte. Stattdessen ist der Zugriff auf die Designer-Datei möglich, die immer neben einer normalen vb-Datei existiert und die Generierung sämtlicher Steuerelemente beinhaltet.
Bevor wir das Projekt ausführen können, müssen wir die .NET-Verweise für das Projekt definieren. Diese Möglichkeit finden wir unter "Projekt" und "Verweise bearbeiten…". Hier wählen wir dann die nachfolgend ersichtlichen Verweise:
mono bringt das .NET-Framework gleich mit.Standardmäßig arbeitet mono mit den gtk-Verweisen, eigene Klassenbibliotheken für die Steuerung von Fenstern, Steuerelementen, Datenbankoperationen und einiges mehr. Da wir es hier mit einer waschechten Windows-Forms-Anwendung zu tun haben und unter denselben Rahmenbedingungen arbeiten möchten, verwenden wir hier knallhart die normalen Microsoft .NET-Bibliotheken. Mit diesen vorbereitenden Maßnahmen können wir das Projekt nun einmal kompilieren und ausführen.
Erste Schritte mit dem ProjektNach der Kompilierung stellen wir erstaunt fest, dass das Programm tatsächlich startet und nichts - außer der Titelleiste - darauf hindeutet, dass es sich hier um ein Programm handelt, was auf dem Mac läuft. Dadurch, dass sämtliche Steuerelemente direkt aus der Windows.Forms kommen, werden sie natürlich auch genauso dargestellt und nicht plattformspezifisch gerendert. Nach ein wenig Herumprobieren und Klicken fallen jedoch schon die ersten Macken auf. So ist der Bildschirmaufbau zäh, langsam, mitunter fehlerhaft und oft führen Aktionen jeglicher Art zum Crash des gesamten Programms - ohne, dass ich dabei selbst Mist gebaut hätte.
Ein Windows-Fenster unter Mac OS X. Die Umlaute stehen zwar richtig im Quelltext, werden aber in der kompilierten Anwendung nicht dargestellt.Eine Windows-MessageBox unter Mac OS X! Die Fenstericons werden scheinbar nicht ausgewertet, denn egal, ob man vbInformationen, vbQuestion oder vbExclamation benutzt - es erscheint immer das Lämpchen.Während der Ausführung sammeln sich in der Debug-Ausgabe Fehlermeldungen. Schlagwörter wie "DeviceSynchronize" lassen darauf schließen, dass das Framework oft nicht in der erforderlichen Geschwindigkeit hinterherkommt und sich Threads gegenseitig überholen.So kann es aussehen, wenn man mehrmals hintereinander das gleiche Fenster öffnet.Soviel zum Thema Windows.Forms. Wenden wir uns mal von der Oberfläche ab und schauen wir uns die Anwendungslogik an. Hier gehts um Klassen, Schleifen, Konstruktoren uvm. In Klassen werden üblicherweise Properties (Eigenschaften) benutzt, um Werte, die von außen nicht greifbar sein sollen (= private), kontrolliert zurückzugeben und/oder auch zu setzen. Properties sind handlich und können, im Gegensatz zu Funktionen, beide Aufgaben gleichzeitig erfüllen. Natürlich soll erwähnt werden, dass Funktionen für größere Taten bestimmt sind
Visual Studio ist in dieser Hinsicht recht flexibel. Properties können, müssen aber keinen definierten Datentyp zurückgeben. Sie können sowohl nur-lesend als auch lesend/schreibend ausgeführt werden. Die folgende Property gibt keinen definierten Datentypen zurück und wird daher als "Object" angenommen - eigentlich:
mono sieht das aber ganz anders - naja fast. Das, was eigentlich eine Warnung sein sollte, ist hier noch ein Fehler:
ReadOnly-Properties werden hingegen gar nicht unterstützt … zumindest nicht "abgefangen":
Resultat:
Das disqualifiziert mono leider im jetzigen Stadium noch für eigene, wiederverwendbare Klassen(bibliotheken) (zumindest komplexere). Hier müsste man dann wieder auf Funktionen ausweichen, die zwar letztlich dasselbe tun, für unseren Zweck aber lediglich eine Vermeidungsstrategie darstellen. Übrigens: der Fehler VBNC99999 signalisiert, dass der Compiler gegen die Wand gefahren ist. Auch wenn der Eindruck entsteht, man habe versehentlich ein Objekt nicht erzeugt, so liegt der Fehler keineswegs im Quelltext - in Visual Studio ist der Quelltext problemlos ausführbar.
Wie geht es weiter?Mein kleiner Versuch hat gezeigt, dass mono noch in den Kinderschuhen steckt und für das produktive Arbeiten nicht geeignet ist. Nein, man kann definitiv nicht alle Projekte anstandslos in mono ausführen. mono zeigt aber schon sehr gute Ansätze, was das plattformübergreifende Entwickeln anbelangt. Sicher bedarf mono noch viel Entwicklungsarbeit und Fehlerbehebung, es zeigt aber, dass sich einige Menschen Gedanken gemacht haben, wie man das Potential von .NET auf andere Plattformen bringen kann.