C++ argv[0] - portabel?

badday

Commander
Dabei seit
Sep. 2007
Beiträge
3.023
Moin zusammen,

ich schreibe gerade an einem Programm und muss mich darauf verlassen können, das argv[0] immer den kompletten Programmnamen inkl. Pfad bereitstellt. Des weiteren muss es in Windows mit \ als Seperator sein und in anderes OSes mit / . Kann man sich darauf verlassen?

Wenn nicht, gibt es eine andere Möglichkeit? Ich brauche zumindest den Pfad, in dem das Programm liegt. Gerne auch mit boost.

Vielen Dank.

Gruß,

badday
 

badday

Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
3.023
Danke für den Link! Das heißt dieser Code müsste funktionieren?
Code:
#ifdef _WIN32
inline string GetCurrentDirectory()
{
	
	TCHAR szPathName[_MAX_PATH]; 
   ::GetModuleFileName(NULL, szPathName, _MAX_PATH); 
	string path = szPathName;
	string::size_type idx;
   idx=path.rfind("\\");
	path.erase(idx, string::npos);   
   return path;
	
}
#else
inline string GetCurrentDirectory()
{
	char szTmp[32]; 
	sprintf(szTmp, "/proc/%d/exe", getpid()); 
	
	return (string)szTmp; 
}
#endif
 

refri89

Cadet 4th Year
Dabei seit
Mai 2010
Beiträge
95
so bzw. so ähnlich schreibt man jedenfalls ein Multiplattform Code in C/C++. Der Präprozessor wertet die Macros aus (#ifdef, #else) und entscheidet dann was er compiliert. Normalerweise ist in den C Standard libraries z.B. stdio.h ein #define WIN32 drin, wenn es WinDOS Plattform is, somit trifft der erste Teil zu. Soweit funktioniert das Ganze soweit ichs noch aus meine C/C++ Zeit weiß...
Probiers mal aus, siehst ja wie's funktioniert....
PS: will man Multiplattform Programme schreiben, wär vielleicht mal die Installation der VirtualBox nicht schlecht und darin kann man verschiedene OS installieren, da spart man sich das runtergefahre (auch wenn jetzt gleich wieder jemand schreibt VirtualBox ist ein Scheiß und andere VMs sind viel besser) http://www.virtualbox.org/
Ergänzung ()

http://www.ibm.com/developerworks/aix/library/au-boostfs/index.html
http://www.boost.org/doc/libs/1_43_0/index.html

die boost libraries sind scheinbar nicht kommerziel (da boost.org) und legen nochmal eine Abstraktionsschicht zwischen System und File Operationen, sodaß du den Code nur einmal schreiben mußt und er überall gleich aussieht...
 

badday

Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
3.023
so bzw. so ähnlich schreibt man jedenfalls ein Multiplattform Code in C/C++. Der Präprozessor wertet die Macros aus (#ifdef, #else) und entscheidet dann was er compiliert. Normalerweise ist in den C Standard libraries z.B. stdio.h ein #define WIN32 drin, wenn es WinDOS Plattform is, somit trifft der erste Teil zu. Soweit funktioniert das Ganze soweit ichs noch aus meine C/C++ Zeit weiß...
Probiers mal aus, siehst ja wie's funktioniert....
Natürlich funktioniert das so, dahin zielte meine Frage aber nicht. Ich wollte nur wissen, ob ich mich auf das Funktionieren des Codes auf jedem (halbwegs geläufigen) OS verlassen kann. Ich teste den Code natürlich auf diversen BSes, allerdings kann ich nie alle testen, daher wollte ich wissen, ob mir jemand sagen kann, ob das so immer funktionieren müsste.


PS: will man Multiplattform Programme schreiben, wär vielleicht mal die Installation der VirtualBox nicht schlecht und darin kann man verschiedene OS installieren, da spart man sich das runtergefahre (auch wenn jetzt gleich wieder jemand schreibt VirtualBox ist ein Scheiß und andere VMs sind viel besser) http://www.virtualbox.org/
Da ich das nicht erste seit gestern mache, habe ich das natürlich schon längst. Trotzdem Danke ;)

die boost libraries sind scheinbar nicht kommerziel (da boost.org) und legen nochmal eine Abstraktionsschicht zwischen System und File Operationen, sodaß du den Code nur einmal schreiben mußt und er überall gleich aussieht...
Wie du meinem ersten post entnehmen kannst, habe ich hier schon auf boost verwiesen. Allerdings weiß ich nicht die exakte Funktion für dieses spezifische Problem. Wenn diese jemand weiß, wäre ich sehr dankbar.

Gruß,

badday
 

refri89

Cadet 4th Year
Dabei seit
Mai 2010
Beiträge
95
In argv[0] befindet sich meistens der Programmname, muss aber nicht sein. Ein Beispiel:

char *argv_for_new_app[] = {"ganzAndererName", ....argumente};
char *application = "/bin/bash";
execve(application, argv_for_new_app, envp);

Somit ist in argv[0] der Bash nun eben »ganzAndererName« zu lesen. Das ist u.a. ein effektiver Workaround für DOS/Windows Plattformen, die keine Symlinks haben (d.h. manche Programme erkennen ihre Funktion an argv[0]).


Würd also mal eine Soft und Hard Link in Linux erzeugen und dann das ganze durchprobieren...
 
Zuletzt bearbeitet:

badday

Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
3.023
Nun, ich muss mich auf die Lösung immer verlassen können, daher scheidet argv[0] wohl aus. Die Frage ist, ob es eine sichere, portable Lösung gibt...

Gruß,

badday


#edit: Der Windows-Weg scheint zu funktionieren, unter Linux geht der Weg jedoch nicht. Weiß hier jemand einen? Vielen Dank.
 
Zuletzt bearbeitet:

cx01

Ensign
Dabei seit
Mai 2010
Beiträge
241
Es scheint keine plattformübergreifende Möglichkeit zu geben. Du musst es also für verschiedene Betriebssystem anpassen. Hier, in der obersten Antwort, gibt es eine Liste, welche Methoden man nehmen kann: http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

Die Linux-Variante würde ich ersetzen durch die hier vorgeschlagene: http://stackoverflow.com/questions/200737/get-full-path-of-executable-of-running-process-on-hpux
Also:
Code:
#include <limits.h>
...
  char exepath[PATH_MAX] = {0};
  readlink("/proc/self/exe", exepath, sizeof(exepath));
 

badday

Commander
Ersteller dieses Themas
Dabei seit
Sep. 2007
Beiträge
3.023
OK, danke für den Link. Werde das ganze noch mit boost kombinieren, sollte dann funktionieren.

Gruß,

badday
 
Top