Pfad zur eigenen Anwendung
-
Hallo zusammen,
bin ein C++ Neuling und habe lange Zeit mit Delphi programmiert. Da ich auf ubuntu umgestiegen bin, will ich auch die für Linux "nativsten" Sprachen C bzw. C++ erlernen.
Zum Einstieg programmiere ich gerade ein kleines Spielchen (Arkanoid-Klon) mit der Allegro-Bibliothek. Ich komme soweit ganz gut zurecht. Da C++ im Allgemeinen und auch die Allegro-Bibliothek plattform-übergreifend sind, überlege ich mir sogar, das Spiel für Linux und Windows zu kompilieren.
Eine Sache habe ich aber im Netz nicht ausfindig machen können: Wie kann ich dynamisch den Pfad (unter Linux UND Windows) zur eigenen Anwendung ermitteln? Geht das mit den Standard-C++-Funktionen überhaupt?
Der Hintergrund ist, dass ich die Bilder, die im Spiel genutzt werden, in Unterordnern platzieren will und der string zu diesen Ordnern soll dynamisch erstellt werden. Hier sehe ich auch das Problem, dass Linux '/' und Windows '\' Seperatoren benutzt, aber das ließe sich ja vor dem Kompilieren noch schnell abändern.
Bin für alle Infos dankbar!
Dank im voraus und Gruß
-
mit man: getpid(2) kannst du die PID vom Prozess ermitteln. Wo die Binary sich befindet, verrät
/proc/<pid>/exe
, was ein symlink auf die Binary ist. Mit man: readlink(2) bekommst du dann den richtigen Pfad zur Binary.In der Regel wird es aber
/bin, /usr/bin, /usr/local/bin
oder ein Pfad, wo du keine Schreibrechte hast. Bist du sicher, dass du den Pfad der Binary haben willst und nicht den Pfad, von wo aus das Program gestartet wurde? In diesem Fall kannst du ihn mitgetenv("PWD")
ermitteln.
-
Peter G. schrieb:
Hier sehe ich auch das Problem, dass Linux '/' und Windows '\' Seperatoren benutzt, aber das ließe sich ja vor dem Kompilieren noch schnell abändern.
Glücklicherweise kommt Windows auch mit '/' als Pfad-Trenner zurecht, also kannst du getrost darauf setzen.
-
Peter G. schrieb:
Der Hintergrund ist, dass ich die Bilder, die im Spiel genutzt werden, in Unterordnern platzieren will und der string zu diesen Ordnern soll dynamisch erstellt werden. Hier sehe ich auch das Problem, dass Linux '/' und Windows '\' Seperatoren benutzt, aber das ließe sich ja vor dem Kompilieren noch schnell abändern.
Dafür ist der Anwendungspfad aber völlig uninteressant. Unter Unix platziert man sowas zB unter /usr/share/anwendungsname oä.
-
Wie wärs mit relativen Pfaden zu arbeiten?
-
supertux schrieb:
(..) In der Regel wird es aber
/bin, /usr/bin, /usr/local/bin
oder ein Pfad, wo du keine Schreibrechte hast. Bist du sicher, dass du den Pfad der Binary haben willst und nicht den Pfad, von wo aus das Program gestartet wurde? In diesem Fall kannst du ihn mitgetenv("PWD")
ermitteln.Nach den Antworten von dir und [user]nman[/user] bin ich mir nicht mehr so sicher.
nman schrieb:
Peter G. schrieb:
Der Hintergrund ist, dass ich die Bilder, die im Spiel genutzt werden, in Unterordnern platzieren will und der string zu diesen Ordnern soll dynamisch erstellt werden. Hier sehe ich auch das Problem, dass Linux '/' und Windows '\' Seperatoren benutzt, aber das ließe sich ja vor dem Kompilieren noch schnell abändern.
Dafür ist der Anwendungspfad aber völlig uninteressant. Unter Unix platziert man sowas zB unter /usr/share/anwendungsname oä.
Hab' ich das richtig verstanden: Unter Linux platziere ich alle Dateien (außer der Anwendung selbst), die eine Anwendung benötigt unter "/usr/share/anwendungsname/"? Das hieße, dass ich eine Anwendung nicht ohne Veränderung für Linux und Windows kompilieren könnte, da unter Windows Ressourcen, die nicht verändert werden, in der Regel mit im Programmverzeichnis abgelegt werden. Ein weiteres Problem ist, dass ich ja dann so eine Art Installer (.deb Paket?) schreiben müsste?
Habt ihr mir zu diesem Thema Literaturlinks?
Gruß
-
So schwer ist das nicht, das für Linux und Windows zu schreiben.
Struktur unter Windows:APPDIR - bin - share - APPNAME - deine Resourcen - doc - ...
Unter Linux haust du jetzt alles in /usr/bin und in /usr/share/appname. Dann schreibst du ne kleine Funktion oder Klasse die die PFade jeweils für Linux oder Windows zurückgibt. So kannst du relativ leicht x-platform arbeiten. "Große" Gui-Toolkits wie wxWidgets haben dafür Klassen wie wxStandardPathes,vllt da mal in die Sourcen peeken..
rya.
-
Fest einkompilierte absolute Pfade wie /usr/share/, sind nur ok wenn sie sich wenigstens über Compile-Optionen (configure etc.) ändern lassen.
Man kann es auch wie unter Windows haben und einfach alles in ein Verzeichnis packen das man dann nach /opt oder so schiebt.
Statt dem Programm ruft man dann ein Wrapper-Shell script auf, das kann aus $0 den Pfad des Programms lesen.
Beispiel:#!/bin/sh export MY_APP_PATH=$(dirname $0) exec $MY_APP_PATH/prog.exe "$@"
Die Anwendung kommt dann auch über $MY_APP_PATH an die Daten.
supertux schrieb:
getenv("PWD")
dafür lieber getcwd()
-
Hi nochmals,
bei mir wirft sich gerade die Frage auf wie ihr programmiert. Als IDE benutze ich netbeans und wenn ich ein Projekt erstelle, dann packt netbeans mir alle Projektdateien in einen Ordner. Wenn ihr programmiert platziert ihr dann gleich alle Ressourcen-Dateien in /usr/share/appname oder macht ihr das erst zum Schluss?
Auf jeden Fall danke für die Antworten. Ich werde Scorcher24's Idee umsetzen, da ich wxWidgets bereits installiert hatte (wohl wissend, dass ich das mal brauchen werde
).
Gruß
-
Meine Struktur beim Programmieren
Projekt - src - docs - obj - scripts - bin - $compilername -> kompilate - share - appname -> myResource.dat etc
Und die Klasse die ich habe, gibt dann im DEVMODE (Prärpozessoreinstellung) eben nur "../" und nicht "/usr/" oder halt das Windowspendant als prefix zurück.
rya.
-
Peter G. schrieb:
Ich werde Scorcher24's Idee umsetzen, da ich wxWidgets bereits installiert hatte (wohl wissend, dass ich das mal brauchen werde
).
ist jetzt zwar egal, da ausser dir wohl eh niemand dein Programm installieren wird aber prinzipiell ist es absolut Banane einfach feste Pfade vorzuschreiben (und dann auch noch /usr, wenn dann /usr/local!).
Der "richtige" Weg geht über Compile-Optionen oder eben das Shell-Script, so machen es auch andere platformübergreifende Programme wie firefox etc.
-
Hallo DrGreenthumb,
DrGreenthumb schrieb:
Peter G. schrieb:
Ich werde Scorcher24's Idee umsetzen, da ich wxWidgets bereits installiert hatte (wohl wissend, dass ich das mal brauchen werde
).
ist jetzt zwar egal, da ausser dir wohl eh niemand dein Programm installieren wird aber prinzipiell ist es absolut Banane einfach feste Pfade vorzuschreiben (und dann auch noch /usr, wenn dann /usr/local!).
Der "richtige" Weg geht über Compile-Optionen oder eben das Shell-Script, so machen es auch andere platformübergreifende Programme wie firefox etc.Die Sache ist die: Ich will es schon gleich von Anfang an richtig erlernen, aber du musst verstehen, dass ich sowohl in Linux als auch in C++ ein ziemlicher Anfänger bin, daher kann ich mit dem Post:
DrGreenthumb schrieb:
Fest einkompilierte absolute Pfade wie /usr/share/, sind nur ok wenn sie sich wenigstens über Compile-Optionen (configure etc.) ändern lassen.
Man kann es auch wie unter Windows haben und einfach alles in ein Verzeichnis packen das man dann nach /opt oder so schiebt.
Statt dem Programm ruft man dann ein Wrapper-Shell script auf, das kann aus $0 den Pfad des Programms lesen.
Beispiel:#!/bin/sh export MY_APP_PATH=$(dirname $0) exec $MY_APP_PATH/prog.exe "$@"
Die Anwendung kommt dann auch über $MY_APP_PATH an die Daten.
supertux schrieb:
getenv("PWD")
dafür lieber getcwd()
nichts anfangen, einfach weil es mir zu hoch ist. Ich bin nicht beratungsresistent und auch kein Programmieranfänger und ich lese mir auch alle Anleitungen durch bis ich mit etwas anfange. Wenn du mir das etwas genauer erklären könntest oder mir einen Literaturlink geben würdest, würde mir das schon mehr weiterhelfen.
Gruß
-
die 3 Zeilen da im Codeblock sind ein shell-Script. Da musst du nur prog.exe durch den Namen deiner ausführbaren Datei ersetzen und dann das Script aufrufen statt direkt dein Programm.
In dem Programm kommst du dann mit getenv("MY_APP_PATH") an den Pfad wo das Script (und dein eigentliches Programm) liegt und kannst relativ zu diesem Pfad deine Daten finden.