WinRT, das API für die Zukunft von Windows

Gestatten WinRT (Teil 2)
Kommentare

Language Projections
Würde WinRT nur verbesserte Versionen von P/Invoke und COM-Interop enthalten, hätten die Windows-Entwickler von Microsoft schlechte Arbeit geleistet. Anwendungsentwicklung findet

Language Projections

Würde WinRT nur verbesserte Versionen von P/Invoke und COM-Interop enthalten, hätten die Windows-Entwickler von Microsoft schlechte Arbeit geleistet. Anwendungsentwicklung findet heute in der Praxis in abstrakteren Programmiersprachen als C statt. Niemand kann auf Klassen, Events, Exceptions usw. verzichten. Wollen wir jedoch direkt auf Betriebssystemfunktionen zugreifen, nähern wir uns immer mehr dem Kern von Windows und damit einer Ebene, in der Fehler als HRESULT, Strings als Handles und Interfaces als VTables abgebildet werden. Falls Sie mit diesen Begriffen nicht vertraut sind, keine Angst: Diese Konzepte für Sie zu abstrahieren, ist die Aufgabe der Language Projection Layer von WinRT. Egal ob Sie .NET-, C++- oder JavaScript-Entwickler sind, WinRT-Objekte sollen sich für Sie in Ihrer Programmiersprache so natürlich und gewohnt wie möglich anfühlen. Mit „natürlich und gewohnt“ sind beispielsweise in C# Dinge wie die folgenden gemeint:

Abb. 3: Architektur eines WinRT-Objekts am Beispiel von FileInformation
Abb. 3: Architektur eines WinRT-Objekts am Beispiel von FileInformation
  • Der C# Compiler wandelt die rein interfacebasierende WinRT-Basisinfrastruktur in für C# übliche Klassenstrukturen um. Abbildung 3 stellt das Vorgehen schematisch dar [15]. In C# verwendet man wie gewohnt die Klasse (Runtime Class). Im Hintergrund läuft jedoch alles über Interfaces. Die Aktivierung der Klasse erfolgt mithilfe der Registry. Für IntelliSense und zum Generieren von Code durch den Compiler wird auf die Metadaten (WinMD-Dateien) der WinRT-Komponente zugegriffen.
  • Statt HRESULT arbeitet man mit Exceptions.
  • HSTRINGS werden auf den in C# üblichen Datentyp System.String gemapped.
  • Namenskonventionen werden automatisch an die jeweilige Plattform angepasst. Abbildung 2 zeigt dafür ein Beispiel. Vergleichen Sie die C#-Implementierung des WinRT-Objekts auf der rechten Seite und IntelliSense in JavaScript links. Sie sehen, dass die Methodennamen, die in C# mit einem Großbuchstaben beginnen, durch die WinRT Language Projection Layer auf die in JavaScript übliche CamelCase-Schreibweise geändert wurden. Ähnliches gilt für Collections. Die Methode zum Hinzufügen eines Elements heißt in C# Add, in C++ Append und in JavaScript append, obwohl der gleiche Typ dahinter steckt.

Listing 1 ist bewusst sehr einfach gehalten. Der Code bringt die Erklärungen jedoch auf den Punkt. Mithilfe der Klasse Geolocator wird in diesem Beispiel die aktuelle geografische Position ermittelt. Geolocator ist Teil des API des Betriebssystems von Windows. Im Gegensatz zu .NET gibt es jedoch keinerlei Wrapper-Code zwischen unserem Beispiel und dem Betriebssystem. Das Programmiermodell fühlt sich trotzdem ganz natürlich und typisch für C# an. Wir können das Ergebnis der asynchronen Methode mit await abwarten, es ist kein Interop-Code wie beim alten Windows API notwendig, COM ist für uns in keiner Weise sichtbar, Fehler würden uns über eine Exception angezeigt, die wir fangen könnten u. v. m.

Listing 1

using System;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml;

namespace WebCamFotoApp
{
  partial class MainPage
  {
    public MainPage()
    {
      InitializeComponent();
    }

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
      var locator = new Geolocator();
      var position = await locator.GetGeopositionAsync();
      this.Result.Text = string.Format("Lat: {0}, Long: {1}", 
          position.Coordinate.Latitude, position.Coordinate.Longitude);
    }
  }
}  

Die Language Projection von WinRT funktioniert in beide Richtungen: Sie können einerseits bequem und ohne jegliche Wrapper Assemblies direkt die Betriebssystemfunktionen des Windows Kernel verwenden. Andererseits können Sie aber auch in C# eigene WinRT-Objekte entwickeln und die Verwendung des entsprechenden Codes dadurch in JavaScript und C++ möglich machen. Damit eine C#-Klasse zum WinRT-Objekt wird, erstellen Sie mit der Visual Studio 2011 Developer Preview ein C#-Class-Library-Projekt. Im zweiten Schritt ändern Sie in den Projekteigenschaften den Output type von Class Library auf WinMD File. Es liegt in der Natur der Sache, dass Sie bei der Entwicklung von WinRT-Objekten in der öffentlich erreichbaren Schnittstelle (z. B. Klassen, Methoden, Eigenschaften etc.) nicht alles von C# verwenden können. Der Grund dafür ist, dass der C# Compiler ihren Code so umbauen muss, dass er den WinRT-Konventionen entspricht. Im Folgenden werden einige exemplarische Beispiele für Einschränkungen und vom Compiler gemachten Änderungen aufgezeigt, auf die Sie achten müssen (der Compiler liefert entsprechende Fehler, falls Sie gegen eine der bestehenden Regeln verstoßen):

  • Klassen müssen sealed sein, wenn sie von JavaScript aus verwendbar sein sollen.
  • Bei den Datentypen müssen Sie sich in nach außen sichtbaren Komponenten auf die von WinRT definierten, bekannten Typen beschränken (z. B. IList statt List etc.; eine genaue Erläuterung der Einschränkungen finden Sie unter [10]).
  • Da WinRT intern interfacebasierend arbeitet, generiert der Compiler automatisch für jede Klasse ein Interface (Sie können dieses Verhalten nachvollziehen, indem Sie die erzeugte WinMD-Datei mit ildasm.exe oder Reflector öffnen).

Die rechte Seite von Abbildung 2 zeigt ein einfaches Beispiel einer in C# entwickelten WinRT-Komponente. C++ nimmt unter den WinRT-kompatiblen Programmiersprachen eine besondere Rolle ein. Dort ist es möglich, ausschließlich mit den standardisierten Sprachelementen ohne jegliche Microsoft-Erweiterungen WinRT zu konsumieren und WinRT-Objekte zu erstellen. C++-Entwickler haben daher mehrere Varianten, mit WinRT zu arbeiten:

  1. Völlig ohne jede Unterstützung durch Bibliotheken oder Compiler-Erweiterungen. Das ist ein Ansatz, der von rein akademischem Interesse ist und der keine praktische Bedeutung hat.
  2. Wie die ATL (Active Template Library [11]) zu COM verhält sich die neue Windows Runtime Library (WRL [12]) zu WinRT. Bei der WRL handelt es sich um eine Klassenbibliothek, die keinerlei Spracherweiterungen von C++ voraussetzt, den Umgang mit WinRT jedoch durch verschiedene Hilfsklassen erleichtert. Lesern, die viel Erfahrung mit COM und C++ haben, empfehle ich bei Interesse das Lesen der beiden Blog Postings von Ian Griffiths [13], [14]. Microsoft verwendet die WRL intern zur Entwicklung von WinRT. Zum Zeitpunkt des Schreibens dieses Artikels gibt es de facto keine Dokumentation der WRL in der MSDN Library. Im Programmieralltag werden nur sehr wenige Entwickler die Notwendigkeit spüren, mit der WRL zu arbeiten.
  3. Der effizienteste Weg mit WinRT und C++ zu programmieren, ist C++/CX. C++/CX erweitert den C++ Compiler um einige zusätzliche Sprachkonstrukte, die das Entwickeln und Verwenden von WinRT-Objekten stark vereinfachen. C++/CX erstellt, auch wenn die Syntax aussieht wie C++/CLI, nativen Code und keinen managed Code. Der Performance-Overhead im Vergleich zur WRL ist minimal, der Produktivitätsgewinn aber massiv.

Ich möchte an dieser Stelle nicht näher auf die WRL und C++/CX eingehen, da wir diesem Thema in einer der nächsten Ausgaben dieses Magazins einen eigenen Artikel widmen werden.

WinRT-Klassenbibliothek

Wie eingangs erwähnt, ist der dritte Teil von WinRT die Klassenbibliothek, die Entwickler bei der Erstellung von Metro Style Apps unterstützt. Für .NET-Projekte steht dafür ein eigenes Profil zur Verfügung, das in der Visual Studio 2011 Developer Preview in den Projekteigenschaften eingestellt wird (Abb. 4). Es beschränkt Sie als .NET-Entwickler auf eine begrenzte Anzahl an Klassen aus dem .NET Framework, fügt aber die gesamte Funktionalität von WinRT hinzu. Microsoft hat die Gelegenheit genutzt und im Zuge der Einführung von WinRT die Klassenbibliothek aufgeräumt. Obsolete Teile und Doppelgleisigkeiten wurden entfernt, Designfehler wurden korrigiert. Es war ausdrücklich kein Ziel von Microsoft, rückwärtskompatibel zu bleiben; die Umstellung sollte aber einfach bleiben. Sie dürfen in der Praxis nicht damit rechnen, dass Ihr bestehender Code vollständig ohne Änderungen in Metro Style Apps funktionieren wird.

Abb. 4: Das .NET-Profil für Metro Style Apps
Abb. 4: Das .NET-Profil für Metro Style Apps

Der größte Unterschied zwischen dem Metro-Style-Profil und dem vollwertigen .NET Framework ergibt sich aus der Tatsache, dass das neue Profil ganz und gar auf die Entwicklung von Metro Style Apps für Windows 8 ausgerichtet ist. Erwarten Sie vom Metro-Style-Profil nicht alle Funktionen, die Sie von WPF oder Silverlight kennen. Die größte Ähnlichkeit in Sachen UI-Funktionsumfang hat das neue Profil mit dem Windows Phone 7. Eine detaillierte Zusammenstellung aller Änderungen, Neuigkeiten und Einschränkungen des Metro-Style-Profils finden Sie im Slidedeck des Vortrags von Krzysztof Cwalina [16]. Eine detaillierte Behandlung all dieser Unterschiede würde leider den Rahmen dieses Artikels sprengen.

Was bedeutet WinRT für die Zukunft der .NET-Klassenbibliothek? Sie wird definitiv schlanker. Durch die oben beschriebenen Mechanismen der WinRT Language Projection fällt ein großer Teil der Klassenbibliothek komplett weg, da das neue API des Windows Kernels in .NET direkt zur Verfügung steht. Die Zahlen sprechen in dieser Hinsicht eine deutliche Sprache: Während .NET 4.5 rund 14 000 Typen enthält und das Windows Phone 7 immerhin noch etwa 2000 vorweisen kann, sind im Metro-Style-Profil nur noch rund 1000 Typen enthalten. Die Bedeutung der Common Language Runtime sowie der jeweiligen Compiler C# und VB nimmt im Vergleich zur Bedeutung der .NET-Klassenbibliothek zu. Es gibt jedoch nicht den geringsten Grund zu behaupten, dass WinRT mit dem Metro-Style-Profil als das Ende von .NET bezeichnet werden kann.

Zusammenfassung

WinRT ist die Laufzeitumgebung für Metro Style Apps. Mit ihr bringt Microsoft Windows in das Zeitalter der Apps. WinRT baut auf den bewährten Prinzipien von COM auf, entwickelt sie jedoch in vielen Bereichen weiter. Eine besondere Leistung ist die nahtlose Einbindungsmöglichkeit des API des Betriebssystems in verschiedene Programmiersprachen, die vor allem das Metadatenkonzept von WinRT möglich macht. Entwicklerteams werden dadurch flexibler, da die verschiedenen Sprachen je nach Aufgabenstellung und vorhandenem Know-how kombiniert werden können. Heute liefert Microsoft C++, C#, VB und JavaScript als WinRT-kompatible Sprachen; die neue Runtime ist jedoch so gestaltet, dass andere Programmierumgebungen problemlos ähnliche Schnittstellen schaffen können.

Rainer Stropek ist IT-Unternehmer, Softwareentwickler, Trainer, Autor und Vortragender im Microsoft-Umfeld. Er ist seit 2010 MVP für Windows Azure und entwickelt mit seinem Team die Zeiterfassung für Dienstleistungsprofis: time cockpit (www.timecockpit.com).
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -