C ++ Найти путь выполнения на Mac - PullRequest
2 голосов
/ 10 августа 2011

Допустим, мой исполняемый файл расположен в /Users/test_user/app на Mac OSX, и я запускаю его с /Users/test_user/Desktop/run_app:

Desktop run_app$ /Users/test_user/app/exec 

В моем коде C ++ как найти путь к расположениюисполняемый файл (который в этом случае будет /users/test_user/app)?Мне нужно сослаться на некоторые другие файлы по этому пути в моем коде и не хочу указывать абсолютные пути в коде, поскольку некоторые пользователи могут поместить папку в другое место.

Ответы [ 4 ]

3 голосов
/ 10 августа 2011

При условии, что я вас правильно понимаю, вы должны быть в состоянии использовать NSProcessInfo -arguments метод для получения пути к исполняемому файлу.

Для смешивания в Objective-Cкод с кодом C ++, вы можете просто изменить расширение имени файла рассматриваемого исходного файла с .cpp на .mm.Затем добавьте Foundation.framework в фазу сборки Link Binary With Library вашей цели.

[РЕДАКТИРОВАТЬ] обновлен, чтобы показать разницу между argv[0] и [[[NSProcessInfo processInfo] arguments] objectAtIndex:0].

Затем, чтобы использовать код, вы можете сделать что-то вроде следующего кода:

#include <iostream>

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // print out raw args
    NSMutableArray *arguments = [NSMutableArray array];
    for (NSUInteger i = 0; i < argc; i++) {
            NSString *argument = [NSString stringWithUTF8String:argv[i]];
            if (argument) [arguments addObject:argument];
    }

    NSLog(@"arguments == %@", arguments);

    const char *executablePath =
       [[[[NSProcessInfo processInfo] arguments] objectAtIndex:0]
                                             fileSystemRepresentation];

    printf("executablePath == %s\n", executablePath);

    const char *executableDir =
         [[[[[NSProcessInfo processInfo] arguments] objectAtIndex:0]
             stringByDeletingLastPathComponent] fileSystemRepresentation];

    printf("executableDir == %s\n", executableDir);

    [pool release];

    return 0;
}

Если я тогда cd войду в родительский каталог исполняемого файла, а затем выполню исполняемый файл, используя относительный путь:

MacPro:~ mdouma46$ cd /Users/mdouma46/Library/Developer/Xcode/DerivedData/executablePath-ewememtbkdajumdlpnciyymduoah/Build/Products/Debug

MacPro:Debug mdouma46$ ./executablePath blah blah2

Я получу следующий вывод:

2011-08-10 12:59:52.161 executablePath[43554:707] arguments == (
    "./executablePath",
    blah,
    blah2
)

executablePath == /Users/mdouma46/Library/Developer/Xcode/DerivedData/executablePath-ewememtbkdajumdlpnciyymduoah/Build/Products/Debug/executablePath

executableDir == /Users/mdouma46/Library/Developer/Xcode/DerivedData/executablePath-ewememtbkdajumdlpnciyymduoah/Build/Products/Debug

Таким образом, хотя argv[0] не обязательно может быть полным путем, результатом, возвращаемым из [[[NSProcessInfo processInfo] arguments] objectAtIndex:0], будет.

Итак, есть [[[NSProcessInfo processInfo] arguments] objectAtIndex:0], или немного более простой подход - просто использовать NSBundle сам по себе, даже если это инструмент командной строки (см. Что такое «основной пакет» инструмента основания командной строки? ):

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
const char *executablePath =
    [[[NSBundle mainBundle] executablePath] fileSystemRepresentation];
[pool release];
2 голосов
/ 10 августа 2011

man 3 dyld говорит:

_NSGetExecutablePath () копирует путь основного исполняемого файла в буфер buf.Параметр bufsize должен изначально быть размером буфера.Эта функция возвращает 0, если путь был успешно скопирован.Возвращает -1, если буфер недостаточно велик, а * bufsize установлен на требуемый размер.Обратите внимание, что _NSGetExecutablePath () вернет «путь» к исполняемому файлу, а не «реальный путь» к исполняемому файлу.То есть путь может быть символической ссылкой, а не реальным файлом.С глубокими каталогами общий необходимый размер буфера может быть больше, чем MAXPATHLEN.

#include <mach-o/dyld.h>
#include <limits.h>

int main(int argc, char **argv)
{
  char buf [PATH_MAX];
  uint32_t bufsize = PATH_MAX;
  if(!_NSGetExecutablePath(buf, &bufsize))
    puts(buf);
  return 0;
}
2 голосов
/ 10 августа 2011

Если это «настоящее» приложение для OS X, правильный способ сделать это - создать пакет:

http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFBundleRef/Reference/reference.html

1 голос
/ 10 августа 2011

Может быть, вы могли бы использовать команду which.http://unixhelp.ed.ac.uk/CGI/man-cgi?which

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...