Managed und unmanaged Code
Als C++ Entwickler kommt man unter Umständen zu den Fall managed und unmanaged Code in einem einzigen Projekt verwalten zu müssen. Was ist der unterschied und warum ist das relevant?
Managed und unmanaged Code
Die Unterscheidung zwischen managed und unmanaged Code ist überaus wichtig, meist in einem Projekt aber nicht relevant. Erst wenn man in die Situation kommt diese beiden Code Arten zu mischen wird es interessant. Der Unterschied der beiden Typen ist schnell erklärt:
- unmanaged Code
klassischer C++ Code. Man muss sich selbst um die Speicherverwaltung kümmern. Das bedeutet: alles was mit new oder new[] an Speicher angefordert wurde sollte zur Laufzeit auch wieder mit delete und delete[] freigegeben werden. Fehler führen zu Memory Leaks und langfristig (wenn das Programm länger läuft) zum Absturz des Systems. Der Vorteil ist, dass man gezwungen wird selber eine für das Programm optimale Lösung zu finden und somit Performance gegenüber der anderen Methode gewinnt. - managed Code
jeder Code der über eine virtuelle Maschine ausgeführt wird (zum Beispiel C#, JAVA, …). Speicher wird über einen Garbage Collector dynamisch zur Laufzeit entfernt, als Entwickler braucht man sich dazu wenig Gedanken machen. Es entsteht jedoch ein Overhead durch zusätzliche Strukturen und Algorithmen die den Speicher prüfen.
Es gibt also eine klare Trennung von diesen Arten Software zu programmieren und auszuführen. In C# ist es nicht möglich unmanaged Code zu schreiben und im Gegensatz dazu ist in C++ jeder Code unmanaged.
Das Problem
Als Programmierer wird man sich wenig Gedanken machen wo Code wie ausgeführt wird. Unter Visual C++ gibt es jedoch die Möglichkeit, dass man externen C# Code ins C++ Projekt einbinden kann – das funktioniert mittels dem Compilerflag „/clr“ (Commond Language Runtime).
Dieses Flag kann man global für das ganze Projekt oder für jedes einzelne Codefile (C++ Klasse) setzen. Sobald man dieses Flag gesetzt hat ist es möglich .NET Code unter C++ zu verwenden.
.NET Code verwenden
Die gemeinsame Schnittstelle ist nun in C# für .NET implementiert. Wir können diese nun auch unter C++ verwenden. Das folgende Beispiel zeigt anhand einer Standard .NET Klasse, wie man diese unter C++ anlegt:
System::Object ^x = gcnew System::Object();
Jede .NET oder managed Klasse wird mit der genannten Schreibweise angelegt. Dabei ist folgendes interessant: statt einem * für den Pointer wird das Zeichen ^ verwendet. Dieses symbolisiert einen Pointer auf eine managed Klasse. Dieser Pointer muss nicht freigegeben werden, nach der Zuweisung des Speichers übernimmt der Garbage Collector diese Kontrolle. Der Speicher wird mit dem Schlüsselwort gcnew anstatt wie unter C++ üblich new angelegt.
Je nachdem welche .NET Klassen man verwenden möchte muss man unter Visual Studio bei der Solution noch die nötigen Verweise hinzufügen (beispielsweise zu System::Object). Danach kompiliert der Code und man erstellt eine lauffähige Datei, die den speicher teilweise selbst verwaltet und teilweise in der virtuellen Maschine ausgeführt wird.
Fazit
Einmal mehr zeigt sich am managed und unmanaged Code Beispiel wie mächtig C++ Code tatsächlich ist. Eine mittlerweile über die Jahre gekommene Programmiersprache kann mit dem nötigen Compiler und Programmaufbau auch Teile anderer Applikationen verwenden. Gemeinsame Klassenbibliotheken sind dadurch einfach zu realisieren. Alte, über Jahrzehnte entwickelte, C++ Projekte können ohne viel Aufwand auch mit neueren Systemen auf Codeebene angebunden werden. Der unüberwindbar scheinende Graben zwischen zwei Sprachen (C++ und C#) verschwimmt.