C中二进制的路径

sin*_*yma 9 c path

如何获取正在执行的二进制文件驻留在C程序中的路径?

我正在寻找类似于__FILE__ruby/perl/PHP的东西(当然,__FILE__C中的宏是在编译时确定的).

dirname(argv[0])会给我我想要的所有情况,除非二进制文件在用户的$PATH...然后我根本得不到我想要的信息,而是""或者"."

ric*_*chq 16

完全不可移植的Linux解决方案:

#include <stdio.h>
#include <unistd.h>

int main()
{
  char buffer[BUFSIZ];
  readlink("/proc/self/exe", buffer, BUFSIZ);
  printf("%s\n", buffer);
}
Run Code Online (Sandbox Code Playgroud)

这使用"/ proc/self"技巧,它指向正在运行的进程.这样就省去了查找PID的麻烦.错误处理作为练习留给警惕.


i_a*_*orf 8

非便携式Windows解决方案:

WCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, ARRAYSIZE(path));
Run Code Online (Sandbox Code Playgroud)


Mat*_*t J 6

这是一个可能对Linux系统有帮助的示例:

/*
 * getexename - Get the filename of the currently running executable
 *
 * The getexename() function copies an absolute filename of the currently 
 * running executable to the array pointed to by buf, which is of length size.
 *
 * If the filename would require a buffer longer than size elements, NULL is
 * returned, and errno is set to ERANGE; an application should check for this
 * error, and allocate a larger buffer if necessary.
 *
 * Return value:
 * NULL on failure, with errno set accordingly, and buf on success. The 
 * contents of the array pointed to by buf is undefined on error.
 *
 * Notes:
 * This function is tested on Linux only. It relies on information supplied by
 * the /proc file system.
 * The returned filename points to the final executable loaded by the execve()
 * system call. In the case of scripts, the filename points to the script 
 * handler, not to the script.
 * The filename returned points to the actual exectuable and not a symlink.
 *
 */
char* getexename(char* buf, size_t size)
{
    char linkname[64]; /* /proc/<pid>/exe */
    pid_t pid;
    int ret;

    /* Get our PID and build the name of the link in /proc */
    pid = getpid();

    if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid) < 0)
        {
        /* This should only happen on large word systems. I'm not sure
           what the proper response is here.
           Since it really is an assert-like condition, aborting the
           program seems to be in order. */
        abort();
        }


    /* Now read the symbolic link */
    ret = readlink(linkname, buf, size);

    /* In case of an error, leave the handling up to the caller */
    if (ret == -1)
        return NULL;

    /* Report insufficient buffer size */
    if (ret >= size)
        {
        errno = ERANGE;
        return NULL;
        }

    /* Ensure proper NUL termination */
    buf[ret] = 0;

    return buf;
}
Run Code Online (Sandbox Code Playgroud)

基本上,您getpid()用来查找PID,然后找出/proc/<pid>/exe指向的符号链接.

  • 确实; 仅对上面提到的"用于Linux系统"有效.仍在寻找更符合POSIX标准的方法. (2认同)

小智 5

我使用的一个技巧,至少在OS X和Linux上解决$ PATH问题,是制作"真正的二进制" foo.exe而不是foo:文件foo,这是用户实际调用的,是一个存根shell用原始参数调用函数的脚本.

#!/bin/sh

$0.exe "$@"
Run Code Online (Sandbox Code Playgroud)

通过shell脚本重定向意味着真正的程序获得了一个argv[0]实际上有用的程序,而不是可能存在于程序中的程序$PATH.我从标准ML编程的角度写了一篇关于这个博客文章,之前我发现这可能是一个与语言无关的问题.