使用c++确定可执行文件的路径

Determine path to executable using c++

本文关键字:路径 可执行文件 c++ 使用      更新时间:2023-10-16

我正在用c++、flex和GNU bison编写一个简单的语言解释器/翻译器。我需要知道可执行文件的路径。对于简单的情况,如"mylang mysource. exe"。"我可以使用argcargv获得路径,但是如果通过shebang调用该文件,我该怎么办?"#/usr/bin/env mylang")?

还有其他argcargv组合不起作用的情况。有可能克服这种情况吗?如果是这样,我想要得到可执行文件的完整路径。解决方案必须是跨平台的。如果可能的话,我希望避免使用外部库,尤其是boost,它对我的目标来说太大了。谢谢!

这将非常依赖于平台,但对于linux,符号链接"/proc/self/exe"指向当前映像的物理路径。从这里开始,您可以使用readlink来确定路径。我最近用了这个:

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <stdexcept>
#include <boost/scoped_array.hpp>
std::string path;
size_t size = 1024;
const ssize_t err = static_cast<ssize_t>(-1);
while (true)
{
    boost::scoped_array<char> buffer(new char[size]);
    ssize_t res = readlink("/proc/self/exe", buffer.get(), size);
    if (res == err)
    {
        if (errno == ENAMETOOLONG)
            size *= 2; // try again
        else
            throw std::runtime_error("unexpected error during readlink");
    }
    else
    {
        path.assign(buffer.get(), res);
        break;
    }
}

这是使用g++ 4.1.2完成的,所以没有unique_ptr可用,也可以很容易地删除对boost::scoped_array的引用。

注意:这给你的是当前图像的完整路径,而不是图像所在的目录。要获得该目录,需要进行一些操作。Boost Filesystem也有一些很好的功能来做到这一点。否则,您将不得不设法自己解析它。

此外,如果您是一个库,并且不能依赖于更改当前工作目录的另一部分代码,或者无法访问argv,则上述方法非常好。getcwd + argv[0]将工作良好当且仅当您可以保证您的应用程序或库中的任何内容都不会更改当前工作目录(CWD)。argv[0]只有在CWD不变的情况下才有效

另外,如果可执行文件是通过环境变量查找(如$PATH)找到的,则需要实现路径解析以找到您真正所在的位置。argv[0]仅仅返回你是如何启动的。例如,如果你运行命令"ls -al",argv[0]对命令"ls"将只是"ls"。如果你运行"/usr/bin/ls -al", argv[0]将是"/usr/bin/ls"。