如何使用独立于平台的方法在C中获取执行程序目录?

时间:2010-06-11 13:05:18

标签: c cross-compiling glibc glib

我在Linux中为unix和win32(在每个构建时交叉编译)平台开发我的应用程序,所以一个随时可用的函数会很好:)。我正在使用具有gchar* g_get_current_dir(void)函数的glib并返回当前目录,但我真正需要的是可执行文件的目录。我对C编程缺乏经验,所以欢迎任何建议。

3 个答案:

答案 0 :(得分:1)

Windows中的

GetModuleFileName。 linux中的argv[0]

注意:如果您进行跨平台编程,您还应该使用隐藏此层的一些跨平台库(Qt,wxWidgets,ACE,Boost [不知道,但我认为它有一些东西] ......)

答案 1 :(得分:1)

在具有/proc目录的操作系统的Unix下,您可以readlink /proc/self/exe获取实际可执行文件的完整路径,即使argv[0]没有此。< / p>

但是,如果可执行文件以fexecv启动(在许多系统上不可用),并且在系统上实现为系统调用,则可能无效。 fexecvexecve类似,只是传递了一个打开的文件描述符而不是要运行的文件名。在Linux下,它是通过在`“/ proc / self /%i”,fd“生成的字符串上调用execve来实现的,因此文件在程序启动时必须存在于文件系统中。

我认为GNU / Hurd本身支持fexecve

可执行文件可以在文件系统执行后重命名或取消链接,这使得它成为一个未命名的文件,一旦它停止打开就会消失(在这种情况下通常运行文件)要求它由内核打开。

答案 2 :(得分:0)

我不能和窗户说话。但是在UNIX中,有相当一部分时间是可能的,但不能保证。这种情况的原因涉及从shell等其他程序调用exec,在某些情况下可以在可执行文件所在的地方云,例如,像“../../../mybin/exe/myprogram”这样的相对路径。 PATH变量还可以跟踪可执行文件。

让我问一下:你想做什么,或者更确切地说,为什么你需要知道? IMO你不需要知道。你可以检查getcwd(),如果你没有在一个有效的目录中运行,退出。可执行映像的存在位置无关紧要。

这是一个大部分时间都有效的代码块,并非总是如此!

需要来自main的调用,使用argv [0],我使用popen()调用shell来使代码适合小的,popen()并不总是一个很好的选择,如果有的话,这可能会失败PATH中早期的其他可执行文件具有相同的名称:

char *
mypath(const char *src)
{
   FILE *cmd=NULL;
   static char path_2_me[PATH_MAX]={0x0};
   char tmp[PATH_MAX]={0x0};
   const char *basename=strrchr(src, '/');

   if(basename==NULL) 
        basename=src;
   else
        basename++;      

   if(memcmp(src, "./", 2)==0)      
     sprintf(path_2_me,"%s/%s", getcwd(tmp, PATH_MAX), basename);             
   else
   {
      sprintf(tmp, "/usr/bin/which %s", basename);
      cmd=popen(tmp, "r");      
      fgets(path_2_me, sizeof(path_2_me), cmd); /* one read only */
      pclose(cmd);
      /* check for what your version of which says on failure */
      if(memcmp(path_2_me, "no ", 3)==0)
         *path_2_me=0x0;
   }  

   return (*path_2_me) ?path_2_me: NULL;
}