std::string, std::u16string, std::u32string oder doch std::wstring?

Dank „Hello World!“ ist die Zeichenfolge wohl das Erste, was man als Einsteiger in eine neue Program [Mehr]

Arduino mit Visual Studio programmieren

  Vor relativ kurzer Zeit habe ich mir einen Arduino Uno R3 gekauft und ich will euch hier in mehreren Blog Artikeln regelmäßig meine Erfahrungen und Erlebnisse schildern. Für alle, die nicht wissen, was ein Arduino ist, habe ich hier eine kurze Erklärung: Arduino ist eine plattformunabhängige OpenSource Physical-Computing Plattform, die sich aus Software- und Hardwarekomponenten zusammensetzt. Die Hardware besteht aus einem einfachen Board mit Ein / Ausgängen in analoger und digitaler Form. Unter anderem ist auch je nach Modell ein anderer Mikrocontroller auf dem Board verbaut. Als Software wird standardmäßig eine Entwicklungsumgebung verwendet, die auch Personen, die keine Entwicklungsvorkenntnisse haben, Zugang zur Arduino-Programmierung bietet. Ein Beispiel dafür wären Header Dateien, die vollautomatisch im Hintergrund eingefügt werden. Doch was macht den Arduino so besonders? Mit dem preislich sehr günstigen Arduino kann man relativ leicht eigenständige Objekte steuern oder elektronische Schaltungen realisieren. Kunsthochschulen und auch diverse Hersteller von Filmsets verwenden häufig den Arduino als Mikrocontroller um interaktive Installationen aufzubauen oder um zum Beispiel Lichter von Anzeigetafeln blicken zu lassen. Auf dem Arduino wird über eine auf Java basierende IDE in C und C++ programmiert, als Compiler wird hier der “gcc” mit eingebunden. Um die Programmierung zu erleichtern, ist auf dem Arduino Uno R3 eine eigens entwickelte USB-Schnittstelle als „Serial Converter“ verbaut. Mithilfe dieser Schnittstelle ist es möglich, den Arduino über USB mit der IDE zu programmieren. Der Bootloader, der hierfür benötigt wird, ist praktischerweise schon standardmäßig auf dem entsprechenden Controller installiert und kann manuell über die serielle Schnittstelle des Boards konfiguriert werden. Nach meinen ersten Programmierversuchen mit der mitgelieferten IDE lernte ich Visual Studio wieder sehr zu schätzen. Allein die fehlende Auto-Vervollständigung sowie das bessere Syntax Highlighting fehlen einem sehr schnell. Weitere Features, die ich sofort vermisst habe, waren IntelliSense und die Tatsache, dass in VisualStudio Fehler direkt angezeigt werden. Also suchte ich gleich nach meinen ersten Programmierversuchen nach entsprechenden Libaries für Visual Studio. um zumindest den Quellcode in Visual Studio schreiben zu können. Durch einen glücklichen Zufall entdeckte ich im Visual Studio “Extensions”-Menü bei der Wortsuche nach „Arduino“ ein komplettes Plugin, mit dem ich sogar das kompilierte Programm auf den Ardiuno laden konnte. Als erstes muss das erste Projekt her namens “Blink” was man in konventioneller Programmierung mit “Hello World” vergleichen kann. Es besteht darin eine LED blinken zu lassen. Dazu baue ich mir folgende Schaltung bestehend aus einem Arduino Uno R3, 1x Roter LED und einem 220 Ohm Wiederstand. Zum erstellen dieser Bildes habe ich die Open Source Software Fritzing verwendet mit der mit einfach Schritten solche Steckbilder erstellt werden können und auch als Ätzvorlagen exportiert werden können.  So, die Schaltung steht: Jetzt muss ich nur noch das Programm dazu schreiben: Arduino-Programme müssen immer mindestens aus zwei Teilen bestehen: Einmal dem “void setup()” Teil, in dem die Pins konfiguriert werden, und dem Bereich “void loop()”, dessen Codebereich wiederholt ausgeführt wird. Im ersten Bereich weise ich dem digitalen Pin 13 den Typ OUTPUT zu. Im Loop Bereich setze ich den Ausgang von Pin 13 mit der Funktion digitalWrite auf High. Wenn ich jetzt direkt mit der Funktion digitalWrite den Pin wieder auf Low setzen würde, würde er so schnell blinken das wir es nicht als blinken wahrnehmen könnten. Deshalb nehme ich mir die Funktion “delay(1000)” zur Hilfe, die die Schleife 1 Sekunde lang pausieren lässt. Das ganze sieht dann in fertiger Form folgendermaßen: Hier nochmal in schriftlicher Form für die Leute die sich den Code kopieren wollen: 1 void setup() 2 { 3 pinMode(13, OUTPUT); 4 } 5 6 void loop() 7 { 8 digitalWrite(13, HIGH); 9 delay(1000); 10 digitalWrite(13, LOW); 11 delay(1000); 12 } Also fassen wir das Ganze noch einmal zusammen: Der Arduino ist wie im obigen Bild mithilfe einer Steckplatine verkabelt. In Visual Studio haben wir unseren fertigen Code geschrieben. Jetzt müssen wir diesen letztendlich nur noch auf unseren Arduino übertragen. Dazu müssen wir im Visual Studio nur noch unsere Programmversion der Arduino Software (in meinem Fall 1.6), den Arduino Typ (Arduino Uno) sowie den COM Port (COM3)  angeben, der automatisch generiert wird, sobald wir den Arduino über die USB Schnittstelle verbinden. Da wir jetzt unser Programm ohne Stoppunkte ablaufen lassen wollen, müssen wir jetzt noch als Kompilierungstyp “Release” auswählen und anschließend den “Local Windows Debugger” starten. Das ganze sieht dann folgendermaßen aus: Im Output Fenster können wir sehen, dass unser Programm erfolgreich kompiliert wurde und über den COM3 Port hochgeladen wurde. Wenn wir jetzt auf unseren Arduino schauen, können wir beobachten, wie die LED langsam blinkt. Den kompletten Blog Post habe ich auch nochmal in Form eines Video auf Youtube veröffentlicht. Für all die Leute die sich bisher noch nicht mit Development beschäftigt haben oder aus anderen Programmiersprachen wie der C Familie kommen würde ich den Kurs C++ Einführung in die Programmierung empfehlen für den leichteren Einstieg in die Programmierung, da dort die Grundkenntnisse über die Datentypen usw vermittelt werden. In meinem nächsten Artikel werden wir uns dann Programmierung von komplexeren Anwendungen beschäftigen.

Cpp 11 SmartPointer

Eines meiner, und wahrscheinlich vieler, vieler anderer C++ Entwickler, Lieblings-‘Features’ des neunen C++11 Standard sind die sogenannten SmartPointer. “In der Informatik ist ein SmartPointer ein abstrakter Datentyp, der einen Zeiger simuliert und noch zusätzliche Funktionen bietet, wie z.B. automatische Speicherverwaltung. Diese zusätzlichen Funktionen sollen Bugs durch fehlerhafte Verwendung von Pointern reduzieren unter Beibehaltung der Effizienz. In der Regel tracken Smart Pointers auf den Speicher auf welchen sie verweisen. Fehlerhafte Verwendung von Pointern ist einer der häufigsten Gründe für Bugs/Speicherlecks im Programm. SmartPointer verhindern das Auftreten von sog. Speicherlecks, indem sie die Ressourcen-Freigabe automatisieren. Die Ressource eines SmartPointers wird automatisch freigegeben, wenn der letzte (oder einzige) Owner der Ressource zerstört wurde, beispielsweise beim Verlassen des Scopes. Zusätzlich werden hängende Pointer durch den Gebrauch von SmartPointern eliminiert, da diese automatisch die Ressource freigeben. Es gibt verschiedene Arten von SmartPointern. Einige arbeiten mit einem Reference-Count, andere indem sie den Besitz einer Ressource über einen einzigen Pointer für sich fest beanspruchen. In Managed Sprachen (C#, Java, etc.) sind Pointer als natürlich auch SmartPointer überflüssig, da hier die Garbage Collection automatisch durchgeführt wird.” Quelle: Wikipedia Sämtliche dieser neuen SmartPointer befinden sich in dem <memory.h> header file und können dadurch verwendet werden. Im Grunde gibt es 3 Arten dieser Smart Pointer: Unique Pointer Shared Pointer Weak Pointer Jeder von diesen hat besondere Eigenschaften. Das macht diesen somit für bestimmte Anwendungsfälle so gut wie unverzichtbar. Dadurch, dass durch diese Smartpointer Speicherlecks verhindert und Danglingpointer eliminiert werden, gibt es keinerlei Gründe dafür, diese neue Funktionalität nicht bis zum Erbrechen zu verwenden. Dadurch, dass hierbei Templates zum Einsatz kommen, sind die Smartpointer generisch und können somit auf x-beliebige Ressourcen verweisen. Außerdem gibt es einen neuen Initialisierungswert für Pointer ‘nullptr’. Wie bisher auch kann man mit einer einfachen If-Abfrage überprüfen, ob die Speicherallokierung für den jeweiligen Pointer erfolgreich war oder fehlgeschlagen ist.  1: if (p2) // True wenn die Speicherallokierung für p2 erfolgreich war 2: { 3: // Hier könnte ihr Code zu p2 stehen! 4: } Eigenschaften Jeder dieser 3 Smart Pointer hat im Grunde die selben Eigenschaften, welche den Zugriff und die Verwaltung der dahinterliegenden Ressource verwalten. Get Liefert die Speicheradresse der Ressource zurück. 1: std::unique_ptr<int> p1(new int(5)); 2: cout << *p1.get() << "\n"; Reset Löscht den Speicher und setzt den Pointer wieder auf NULL zurück. Sollte noch ein anderer Pointer auf die Ressource verweisen, wird je nachdem welchen Smartpointer man verwendet hat, entweder die Ressource komplett freigegeben oder lediglich der Pointer auf NULL gesetzt. 1: //p1 = double(5) -> p2 = p1 2: p2.reset(); //Deletes the memory 3: p1.reset(); //Depends on Pointer-Type Count Durch den sogenannten Referencecount werden Speicherlecks & Danglingpointer eliminiert. Jeder Smartpointer hat eine Count-Eigenschaft, bei welcher man die Anzahl an Pointern bekommt, welche auf die jeweilige Ressource verweisen. Sobald der Referencecount den Wert 0 erreicht, wird die Ressource automatisch freigegeben. 1: cout << p1.use_count() << "\n"; Swap Diese Methode ermöglicht das ‘Weitergeben’ der Ressource an einen anderen Smart Pointer. Hierbei kann genauso gut mit der Move-Semantik gearbeitet werden. 1: p1.swap(p3); Unique Pointer Der Unique Pointer ist, wie der Name schon sagt, ein Pointer, welcher eine Ressource für sich alleine beansprucht. Sobald nun der Uniqueptr den Scope verlässt, wird automatisch die Ressource auf welche dieser verweist, freigegeben und somit Speicherlecks vermieden. Falls man mit Swap oder Move die Ressource an einen anderen Uniquepointer weitergeben sollte, wird der Ursprungspointer auf NULL zurückgesetzt und der neue Pointer bekommt den Verweis auf die Ressource zugewiesen. Somit wird der Referencecount von 1 nicht überschritten. 1: std::unique_ptr<int> p1(new int(5)); 2: cout << *p1.get() << "\n"; 3: //std::unique_ptr<int> p2 = p1; //Compile error. (UniquePtr max RefCount = 1) 4: std::unique_ptr<int> p3 = std::move(p1); //Übergibt den Besitz der Ressource von p1 an p3 weiter. p1 wird zurückgesetzt. 5: //oder 6: p1.swap(p3); 7: //cout << *p1.get() << "\n"; //Runtime-Exception (Nullreference) 8: cout << *p3.get() << "\n"; 9: p3.reset(); //gibt die Ressource frei 10: p1.reset(); //Keine Operation wird durchgeführt -> RefCount von p1 = 0 somit NULL   Shared Pointer Sind den bisherigen ‘Stupid’ Pointer am ähnlichsten. Mehrere Pointer können auf die Ressource verweisen, jedoch werden auch hier Speicherlecks und Dangling-Pointer durch die selbstständige ‘Garbage Collection’ eliminiert. Anhand des ReferenceCounts kann man jederzeit abfragen, wie viele Pointer derzeit auf die Ressource verweisen. Falls dieser den Wert 0 erreichen sollte, wird die Ressource automatisch freigegeben und somit Speicherlecks vermieden. 1: std::shared_ptr<int> p1(new int(5)); 2: std::shared_ptr<int> p2 = p1; //Beide verweisen auf den selben Speicher 3: cout << p1.use_count() << "\n"; // -> 2 4: 5: p1.reset(); //Speicher exisitert noch -> Refcount 1 6: p2.reset(); //Speicher wird freigegeben -> Refcount 0 Weak Pointer Weak Pointer sind sog. schwache Referenzen (uncounted) auf einen bereits existierenden SharedPtr. Diese schwachen Pointer sind keineswegs schwach oder unnütz, jedoch haben sie nur eine ganz spezifische Aufgabe: das Weitergeben von Ressourcen ohne den ReferenceCount zu erhöhen. Falls nun bis zum Weitergeben der Ressource der Count 0 erreichen sollte, wird diese freigegeben und somit auch der Weak Pointer nutzlos. Mit der Lock()-Methode kann die Ressource, auf welche der Weak Pointer verweist, an andere Shared Pointer weitergeben, falls diese noch nicht freigegeben wurde.   1: std::shared_ptr<int> p1(new int(5)); 2: std::weak_ptr<int> wp1 = p1; //p1 immer noch alleiniger 'Besitzer' des Speichers 3: 4: { 5: std::shared_ptr<int> p2 = wp1.lock(); //P1 & P2 besitzen den Speicher 6: if (p2) // Da P2 über einen WeakPointer initialisert wurde, sollte stets überprüft werden ob die Ressource noch existiert 7: { 8: //Hier könnte ihr Code zu p2 stehen! 9: } 10: } //p2 wird freigegeben (Out of scope) -> p1 alleiniger Besitzer 11: 12: p1.reset(); //Speicher wird freigegeben weil RefCount == 0 13: 14: std::shared_ptr<int> p3 = wp1.lock(); //Speicher ist nicht mehr vorhanden, also bekommen wir einen leeren SharedPtr 15: if (p3) 16: { 17: //Wird nicht ausgeführt 18: }