C++ Find execution path on Mac

两盒软妹~` 提交于 2021-01-27 13:38:35

问题


Lets say my executable is located at /Users/test_user/app on Mac OSX and I am running it from /Users/test_user/Desktop/run_app:

Desktop run_app$ /Users/test_user/app/exec 

Within my C++ code how can I find the path to the location of the executable (which in this case would be /users/test_user/app)? I need to reference some other files at this path within my code and do not want to put absolute paths within the code as some users might place the folder in a different location.


回答1:


man 3 dyld says:

_NSGetExecutablePath() copies the path of the main executable into the buffer buf. The bufsize parameter should initially be the size of the buffer. This function returns 0 if the path was successfully copied. It returns -1 if the buffer is not large enough, and * bufsize is set to the size required. Note that _NSGetExecutablePath() will return "a path" to the executable not a "real path" to the executable. That is, the path may be a symbolic link and not the real file. With deep directories the total bufsize needed could be more than 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:


Provided I'm understanding you correctly, you should be able to use NSProcessInfo's -arguments method to get the executable path.

To mix in Objective-C code with C++ code, you can just change the filename extension of the source file in question from .cpp to .mm. Then add the Foundation.framework to the Link Binary With Library build phase of your Target.

[EDIT] updated to show the difference between argv[0] and [[[NSProcessInfo processInfo] arguments] objectAtIndex:0].

Then to use the code, you could do something like in the following code:

#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;
}

If I then cd into the parent directory of the executable, and then execute the executable using a relative path:

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

MacPro:Debug mdouma46$ ./executablePath blah blah2

I get the following output:

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

So, while argv[0] may not necessarily be a full path, the result returned from [[[NSProcessInfo processInfo] arguments] objectAtIndex:0] will be.

So, there's [[[NSProcessInfo processInfo] arguments] objectAtIndex:0], or a slightly simpler approach is just to use NSBundle itself, even if it is a command-line tool (see What is the "main bundle" of a command-line foundation tool?):

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
const char *executablePath =
    [[[NSBundle mainBundle] executablePath] fileSystemRepresentation];
[pool release];



回答3:


Maybe you could use the which command. http://unixhelp.ed.ac.uk/CGI/man-cgi?which




回答4:


If it's a "real" OS X application the proper way to do it is to create a bundle:

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



来源:https://stackoverflow.com/questions/7004401/c-find-execution-path-on-mac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!