Raspberry Pi Programmierung mit C++ und GTK+
In diesem Tutorial zeige ich wie man mit C++ und GTK+ ein grafisches Fensterprogramm für den Raspberry Pi entwickelt. Zuletzt haben wir ja bereits über ein Script ein grafisches Terminal Programm entwickelt. Mit C++ und GTK+ hat man die größte Flexibilität und kann jede beliebige Anwendersoftware erstellen.
Raspberry Pi Programmierung mit C++ und GTK+
Am Raspberry Pi entwickeln ist etwas für richtige Freaks. Ich habe gerne die maximale Leistung zur Verfügung, weshalb ich das auf meinem i7 Rechner mache. In diesem Tutorial werde ich remote am Raspberry Pi testen und Debuggen, am Laptop jedoch unter Visual Studio entwickeln und kompilieren. Die Entwicklung wäre zwar auch zu 100% auf dem Raspberry Pi möglich, beispielsweise mit der C++ IDE CodeBlocks oder CodeLite, jedoch dauert das kompilieren lange und man benötigt noch Maus und Tastatur…
Projekt einrichten
Beginnen wir also damit unsere Hardware und schließlich das Projekt einzurichten. Ich habe einen Raspberry Pi mit aktuellem Raspbian Buster laufen, der ist im Netzwerk per SSH und VNC verfügbar. Zusätzlich dazu habe ich einen Laptop im selben Netzwerk auf dem Visual Studio 2019 installiert ist. Bevor wir nun ein neues Projekt anlegen können muss sichergestellt werden, dass die erforderlichen Erweiterungen für die IDE installiert sind. Bei mir sind das:
Erst wenn die Linux Entwicklung mit C++ installiert ist, dann können wir ein neues leeres Linux Projekt anlegen. Ansonsten bleibt nur Projekt mit freigegebenen Elementen zur Wahl, wenn C++ als Sprache und Linux als Plattform gewählt wird:
Erstes Beispielprogramm
Das Projekt ist nun angelegt, aber leer. Um nun das erste kleine Programm am Raspberry Pi zu testen müssen wir nun noch eine main.cpp Datei hinzufügen. Dort legen wir gleich ein minimales GTK+ Beispiel an. Über einen Rechtsklick auf den Projektnamen findet man im Kontextmenü den Punkt Hinzufügen. Dort wählen wir „Neues Element…“ und erstellen eine main.cpp:
Der Source Code für ein minimales GTK+ Programm, es wird nur ein Fenster erstellt und angezeigt:
#include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GTK Beispiel"); gtk_widget_show(window); printf("Running gtk_main\n"); gtk_main(); printf("Exiting\n"); return(0); }
Du wirst vermutlich sofort feststellen: es funktioniert nichts. Der Visual Studio Editor mit IntelliSense zeigt jede Menge Fehler an:
Uns fehlt offensichtlich die gtk.h Datei und vermutlich der ganze Rest von GTK, das wir zum kompilieren benötigen. Müssen wir nun GTK und dessen Abhängigkeiten installieren. GTK womöglich selber kompilieren? Kurz: nein! Wir haben ja den Raspberry Pi und dort ist alles nötige zur GTK Entwicklung bereits installiert.
GTK 3 installieren
Damit wir am Raspberry Pi ein GTK Programm kompilieren können benötigen wir die Header Dateien und die Bibliotheken. GTK ist im aktuellen Debian Buster nicht installiert, das können wir aber schnell mit dem Befehlt
sudo apt-get install libgtk-3-dev
ändern. Es werden 100 MB an Daten installiert. Ich verwende bewusst GTK 3, weil es die aktuellste Version ist. Wir stehen aber kurz vor der Veröffentlichung von GTK 4.
Header Dateien freigeben
Unter Raspbian Linux findet man die nötigen Header Dateien zum Kompilieren unter C++ im /usr Verzeichnis. Diesen werden wir nun einfach als Samba Freigabe erstellen und im Visual Studio auf dem Laptop eintragen. Genaue Details zu Samba und dem Raspberry Pi findest du im zuvor verlinkten Artikel. Es müssen folgende Schritte durchgeführt werden:
- Samba installieren
dazu über das Terminal auf dem Raspberry Pi oder über die PowerShell mit SSH verbinden undsudo apt-get install samba
ausführen. Samba ist standardmäßig nicht installiert.
- smb.conf um den Share für /usr erweitern
dazu fügen wir folgende Freigabe ans Ende der smb.conf Datei hinzu. Achtung: die Datei muss mit root Rechten editiert werden:sudo nano /etc/samba/smb.conf
[usr] path=/usr browseable=yes read only=yes valid usr=pi public=yes hide dot files=yes follow symlinks=yes wide links=yes unix extensions=no
- Samba Server neu starten
sudo /etc/init.d/smbd restart
- Zugriff am Windows Laptop (oder PC) testen
über die IP Adresse vom Pi können wir auf den freigegebenen Ordner zugreifen. Wir haben nur Leserechte:
Include Pfad in Visual Studio setzen
Mit dem erstellten Dateizugriff auf dem Raspberry Pi können wir nun auch unter Visual Studio die entsprechenden Include Pfade setzen. Für unser minimales GTK Beispielprogramm benötigen wir lediglich den Header für GTK, dieser ist wie folgt hinzuzufügen:
In den Projekteigenschaften unter C/C++->Allgemein->Zusätzliche Includeverzeichnisse. Achtung: beim Pfad unbedingt immer doppelte Backslashes eingeben. Einfache Backslashes führen unter Umständen zu einem Fehler.
Flags setzen
Um das Projekt erfolgreich zu kompilieren müssen die beiden GTK+ Flags für den Compiler und den Linker gesetzt werden. Das können wir über Visual Studio wie folgt machen:
Als Comiler Flag unter C/C++->Befehlszeile folgendes eintragen:
`pkg-config --cflags gtk+-3.0`
Als Linker Flag unter Linker->Befehlszeile folgendes eintragen:
`pkg-config --libs gtk+-3.0`
Ausgabe konfigurieren
Wir arbeiten zwar am Laptop auf Visual Studio, getestet wird aber am Raspberry Pi. Konsolenprogramme kann man recht einfach auch über Visual Studio, da dort bei der Ausführung eine Linux Konsole angezeigt wird. Was aber bei grafischen Programmen? Wir wollen, dass die Fenster auch am Display vom Raspberry Pi angezeigt werden, das können wir in den Projekteinstellungen vom Visual Studio Projekt unter Debugging->Befehle vor Start auch machen:
Durch „export DISPLAY=:0.0“ wird sichergestellt, dass das Fenster auch am primären Display (dem Desktop Nummer 1 vom Raspberry Pi) gerendert wird. Wir sehen das entweder über einen Monitor, der direkt über HDMI am Raspberry Pi angeschlossen ist, oder über eine aktiven VNC Session.
Kompilieren und Testen
Beim ersten Versuch das Programm zu kompilieren erscheint ein Dialog, in dem wir Verbindungsdaten mit dem Raspberry Pi eingeben müssen:
In dem Dialog gibt man neben der IP Adresse auch den Benutzernamen und das Passwort an. Falls man einen SSH Key hinterlegt hat reicht die Angabe eines privaten Schlüssels und einer eventuell hinterlegten Passphrase. Hat man alles korrekt eingestellt, dann wird das Programm kompiliert und ausgeführt. Ihr solltet nun am Raspberry Pi das geöffnete Fenster des Beispielprogramms sehen:
Auf dem Raspberry Pi erscheint nun wie von Geisterhand ein neues Fenster. Im Visual Studio sieht man im Linux-Konsolenfenster die Ausgabe von printf (Running gtk_main). Damit ist das einfachst mögliche Beispiel zu GTK 3 auch schon fertig. Du erkennst vermutlich gleich, dass es nicht perfekt ist. Man kann das Fenster über das X schließen, das Programm läuft jedoch im Hintergrund weiter. Die Events vom Fenster müssen erst implementiert werden. Einen guten Einstieg in GTK 3 findet man auf der Entwicklerseite von gnome.org.
Fazit
Es braucht schon ein wenig Arbeit um ein GTK 3 remote Linux Projekt für die Entwicklung Fenster basierter Programme am Raspberry Pi aufzusetzen. Ist der Schritt aber einmal getan kann man recht schnell eigene grafische Programme für den Raspberry Pi bauen und testen. Das Setup mit einem Entwicklungssystem und dem Raspberry Pi als Debugsystem ist optimal.
Welche Erfahrungen habt ihr mit diesem Setup gemacht? Wo gibt es noch Probleme oder Unklarheiten?
Vielen dank, dass sie ihre Informationen hier abdrucken und so für mich als Neuling transparent beschreiben. Ich habe zwei Differenzen, die bei mir nicht zum Erfolg führen. Zum einen ist bei den „Zusätzliche Includeverzeichnisse – …….gtk-3.0“ ohne den Anhang %(Addition…., auch kann ich in 192.168….. \user\include\gtk-3.0 nicht finden. Zum zweiten erhalte ich eine Fehlermeldung „Die aktuelle Projektarchitekru „X64“ ist mir der Remotesystemarchitektur „ARM“ nicht kompatibel (ARM). Wchseln Sie im Konfiguratoions Manager zur Projekzarchitektur „ARM“.
Wissen sie wo ich diesen Wechsel vollziehen kann.
Hallo, freut mich, dass dich mein Artikel interessiert und du das Projekt nachbauen willst. Der erste Fehler liegt entweder daran, dass gtk auf dem externen System (Raspberry Pi?) nicht installiert ist oder dass eine falsche Version installiert ist. Was zeigt das /usr/include/ Verzeichnis. Achtung: usr nicht user!!! Das zweite Problem ist einfach erklärt. Man kann C++ Code auf alle möglichen Prozessorarchitekturen bauen. X64 entspricht dabei dem 64-bit System, wie du es vermutlich auf dem Windows 10 Rechner hast. Für den Raspberry Pi musst du die exe als ARM Architektur bauen, dessen Prozessor hat diese Architektur. Ich hoffe das hilft, ansonsten einfach noch weitere Infos posten. Viel Spaß 😉
Hallo Werner, ich möchte das Beispiel auf einem Raspi 1B nachstellen. Gibt es eine Möglichkeit, zu prüfen, ob das Include Verzeichnis gefunden wird ? Ich bekomme im Fehlerfenster von VS 10431 Fehler angezeigt, habe aber den Eintrag unter ‚Konfigurationseigenschaften-C/C++-Allgemein-Zusätzliche Includeverzeichnisse‘, wie ich meine, richtig eingegeben. Es handelt sich primär um E1696 ‚Die Datei “ Quelle“ kann nicht geöffnet werden:…‘ und dann eine Datei xxx.h. Z.B. eine Datei ‚cairo.h‘, die ich unter /usr/include/gtk-3.0/gtk allerdings auch nicht finde. Vielleicht hast due einen Tip ?
Gerd
Hi, ich würde fast tippen da stimmt irgend etwas mit dem smb share nicht. Kannst du von deinem Windows Rechner aus über das Netzwerk auf den /usr Ordner zugreifen? Eventuell passt da auch etwas mit dem Zugriffsberechtigungen nicht.
Hi Werner, hatte das Projekt etwas aus den Augen verloren. Ich habe jetzt den Raspi komplett neu aufgesetzt, das Tutorial neu eingegeben und – das Fenster poppt auf.
Danke für das Teilen deines Wissens !
Gerd
Wunderbar (fast), klappt alles – wie es beschrieben ist – bis auf den Umstand, dass auf dem Pi von keiner einzigen Geisterhand ein Fenster erscheint (-:
Bin alles mehrmals durchgegangen, kann keinen Fehler finden. Hat sich inzwischen irgendwas an irgendwelchen Environments geändert?
BesteGrüße Lino
Sollte eigentlich nach wie vor so funktionieren. Was passiert denn sonst? Siehst du, dass das Programm ausgeführt wird (in der Task Anzeige)? Was meldet denn der Visual Studio Debugger?
… 15 Fehler, u.a. wird die Library nicht gefunden, aber im WinExplorer kann man im /usr- Share browsen. Ich habe das Gefühl, die Authentifikation aus VS heraus funktioniert nicht. Wie muss den das PW in den Konfigurations-Eigenschaften für den Debugger angegeben werden, wenn man keinen SSH Key vergeben hat? besten Dank
Lino
… habe die Verbindung zum Pi im ConnectionManager auch schon x mal neu eingetragen und erfolgreich verifiziert, das CrossPlatformLog sieht auch gut aus, kein Fehler zu sehen – absolut mysteriös das alles.
… Fehler gefunden, danach ging es einwandfrei, nunmehr über Visual Studio 2022
Besten Dank, Lino
Was war der Fehler?
Ha ha Fehler gefunden, ähhtsch. Aber von anderen Hilfe erwarten.
Ich bin am verzweifeln. Ich habe Alles so gemacht wie hier erklärt, aber der Linker macht Probleme. Ich bekomme bei kompilierung für alle Aufrufe „undefined reference“.
Klingt als würde der Compiler die Header Dateien nicht finden. Überprüfe mal ob der Pfad den du bei „Zusätzliche Includeverzeichnisse“ angegeben hast auch über den Explorer erreichbar ist und ob von dort relativ gesehen in deinen Quelldateien die Header korrekt referenziert werden.
Ich komme über den Explorer rein und relativ zu dem Pfad (IP/usr/include/gtk-3.0/gtk/gtk.h) finde ich auch die die Header Datei(en) und kann diese auch öffnen.
Ich hatte zuvor auch einige Intellisense Probleme („Cairo.h kann nicht geöffnet werden“ und ähnliches) die ich behoben habe indem ich weitere Include-Verzeichnisse in VS eingetragen habe (Cairo.h usw.), aber der linker will die Funktionen einfach nicht finden.
Also z.b.: Undefined reference to gtk_init / undefined reference to gtk_window_new / …
P.s.: Danke für die Hilfe 🙂
Hallo, habe auch das Problem, dass hier schon öfter beschrieben wurde. Habe alles nach Anleitung gemacht und erhalte ebenfalls die Errors wie “ undefined reference to `gtk_init‘ „. Auf das Includeverzeichnis kann ich mit dem Explorer zugreifen und die Dateien werden auch auf meinen pi übertragen. D.h. ich finde meinen Projektordner auch auf dem pi wieder und wenn ich dann auf dem pi mit dem Befehl gcc `pkg-config –cflags gtk+-3.0` main.cpp -o example `pkg-config —libs gtk+-3.0` manuell das Programm erstelle, funktioniert das alles und ich kann es auch ausführen. Gruß Jan