在我看来,Linux使用/proc/self/exe很容易但是我想知道是否有一种方便的方法来找到当前应用程序的目录在C/ c++与跨平台接口。我见过一些项目胡乱摆弄argv[0],但它似乎并不完全可靠。
如果你必须支持,比如说,Mac OS X,它没有/proc/,你会怎么做?使用#ifdefs来隔离平台特定的代码(例如NSBundle)?或者尝试从argv[0], $ path和诸如此类的东西中推断可执行文件的路径,冒着在边缘情况下发现错误的风险?
在我看来,Linux使用/proc/self/exe很容易但是我想知道是否有一种方便的方法来找到当前应用程序的目录在C/ c++与跨平台接口。我见过一些项目胡乱摆弄argv[0],但它似乎并不完全可靠。
如果你必须支持,比如说,Mac OS X,它没有/proc/,你会怎么做?使用#ifdefs来隔离平台特定的代码(例如NSBundle)?或者尝试从argv[0], $ path和诸如此类的东西中推断可执行文件的路径,冒着在边缘情况下发现错误的风险?
当前回答
一些特定于操作系统的接口:
Mac OS X: _NSGetExecutablePath() (man 3 dyld) Linux: readlink /proc/self/exe Solaris: getexecname () sysctl CTL_KERN KERN_PROC KERN_PROC_PATHNAME -1 readlink /proc/curproc/file (FreeBSD默认没有procfs) NetBSD: readlink /proc/curproc/exe DragonFly BSD: readlink /proc/curproc/file Windows: GetModuleFileName() with hModule = NULL
也有第三方库可以用来获取这些信息,比如在prideout的回答中提到的whereami,或者如果你使用Qt,评论中提到的QCoreApplication::applicationFilePath()。
可移植的(但不太可靠)方法是使用argv[0]。尽管调用程序可以将它设置为任何东西,但按照惯例,它要么被设置为可执行文件的路径名,要么被设置为使用$ path找到的名称。
一些shell,包括bash和ksh,在执行可执行文件之前将环境变量“_”设置为可执行文件的完整路径。在这种情况下,您可以使用getenv("_")来获取它。然而,这是不可靠的,因为不是所有的shell都这样做,并且它可以被设置为任何东西,或者是在执行程序之前没有更改它的父进程遗留下来的。
其他回答
您可以使用argv[0]并分析PATH环境变量。 看:一个可以找到自己的程序示例
根据QNX Neutrino版本的不同,有不同的方法来查找用于启动运行进程的可执行文件的完整路径和名称。我将进程标识符表示为<PID>。试试下面的方法:
If the file /proc/self/exefile exists, then its contents are the requested information. If the file /proc/<PID>/exefile exists, then its contents are the requested information. If the file /proc/self/as exists, then: open() the file. Allocate a buffer of, at least, sizeof(procfs_debuginfo) + _POSIX_PATH_MAX. Give that buffer as input to devctl(fd, DCMD_PROC_MAPDEBUG_BASE,.... Cast the buffer to a procfs_debuginfo*. The requested information is at the path field of the procfs_debuginfo structure. Warning: For some reason, sometimes, QNX omits the first slash / of the file path. Prepend that / when needed. Clean up (close the file, free the buffer, etc.). Try the procedure in 3. with the file /proc/<PID>/as. Try dladdr(dlsym(RTLD_DEFAULT, "main"), &dlinfo) where dlinfo is a Dl_info structure whose dli_fname might contain the requested information.
我希望这能有所帮助。
除了mark4o的答案,FreeBSD也有
const char* getprogname(void)
它应该也可以在macOS中使用。它可以通过libbsd在GNU/Linux中获得。
依我看,没有这种办法。还有一个不明确的地方:如果同一个可执行文件有多个硬链接指向它,您希望得到什么作为答案?(硬链接实际上并不“指向”,它们是同一个文件,只是位于文件系统层次结构中的另一个位置。)
一旦execve()成功执行了一个新的二进制文件,所有关于原始程序参数的信息都将丢失。
如果您正在编写GPLed代码并使用GNU autotools,那么在许多操作系统(包括Windows和macOS)上处理细节的可移植方法是gnulib的reloctable -prog模块。