在我看来,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和诸如此类的东西中推断可执行文件的路径,冒着在边缘情况下发现错误的风险?
当前回答
根据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.
我希望这能有所帮助。
其他回答
如果你曾经支持过,比如说,麦克 OS X没有/proc/ 你会这么做吗?使用#ifdefs来 隔离特定于平台的代码 (例如NSBundle)?
是的,使用#ifdefs隔离特定于平台的代码是实现这一点的常规方法。
另一种方法是有一个干净的#ifdef-less头,其中包含函数声明,并将实现放在特定于平台的源文件中。
例如,查看POCO(可移植组件)c++库如何为它们的Environment类做类似的事情。
但是我想知道是否有一种方便的方法来找到当前应用程序的目录在C/ c++与跨平台接口。
你不能这样做(至少在Linux上)
因为一个可执行文件可以,在运行它的进程执行期间,重命名(2)它的文件路径到不同的目录(同一文件系统)。请参见syscalls(2)和inode(7)。
在Linux上,一个可执行文件(原则上)甚至可以通过调用unlink(2)来删除(3)本身。Linux内核应该继续分配该文件,直到没有进程再引用它为止。使用proc(5),你可以做一些奇怪的事情(例如重命名(2)/proc/self/exe文件,等等…)
换句话说,在Linux上,“当前应用程序的目录”的概念没有任何意义。
请参阅高级Linux编程和操作系统:三个简单的部分。
还可以在OSDEV上查看一些开源操作系统(包括FreeBSD或GNU Hurd)。其中一些提供了接近POSIX的接口(API)。
考虑使用(在获得许可的情况下)跨平台c++框架,如Qt或POCO,也许可以通过将它们移植到您喜欢的操作系统来对它们做出贡献。
您可以使用argv[0]并分析PATH环境变量。 看:一个可以找到自己的程序示例
如果您正在编写GPLed代码并使用GNU autotools,那么在许多操作系统(包括Windows和macOS)上处理细节的可移植方法是gnulib的reloctable -prog模块。
除了mark4o的答案,FreeBSD也有
const char* getprogname(void)
它应该也可以在macOS中使用。它可以通过libbsd在GNU/Linux中获得。