I have a folder in the same directory as my mac .app and in it is a file called test.ssm. This is trying to be opened by this function:
FILE *input_file = fopen("./data/maps/test.ssm", "r");
The problem is that the application keeps getting the code: EXC_BAD_ACCESS, because it cannot open this file. My project has been set up in xcode using a normal coccoa project. This is an ope开发者_运维百科ngl/glut application.
The problem is that a .app
is a package, and therefore it is actually a directory structure as well, not a "normal" file. Your actual executable is inside the directory YourApp.app/Contents/MacOSX/
. Thus when you use a relative path starting with ./
to open a file in C-code, the executable is actually looking for your file inside the YourApp.app/Contents/MacOSX/
directory, and not the parent directory that the .app
package is installed in.
You can actually browse the directory structure of your .app
by right-clicking on it and choosing View Package Contents
.
If you are going to place files in the file-system that you would like accessible from your executable, either package them inside the .app
, or place them outside the .app
, and place enough ../
in your file access to get you out of the .app
directory structure and into the parent directory where the .app
is installed.
If you want your /data
directory to be inside the .app
package, then you would only have to add enough ../
to your path to get you to out of your /MacOSX
directory and into the root of the .app
where the /data
directory would be found.
Finally, if you need to know the absolute path where your executable is located, you can always use the C-function _NSGetExecutablePath
found inside of mach-o/dyld.h
(i.e., you don't need objective-C). From there you can modify the path to get at any other directory in the file-system relative to where your executable is by trimming it to the proper parent directory and then appending the path name to the file you want to open.
You have to provide absolute file path in Mac OS X, because Mac OS X is built to work with file dialogs or something like that.
As said above, the .app
is a package, or a special folder that the Mac OS X GUI treats like a file. The .app
isn't what's being run, what's being run is your.app/Contents/MacOS/your
, and the current directory refers to your.app/Contents/MacOS/
. If you don't mind using Objective-C in your app (if you're not linking Foundation.framework
already I'd advise you find another way), you can do this to get the path of the app bundle:
const std::string GetApplicationDirectory()
{
id info = [[NSBundle mainBundle] infoDictionary];
NSString *bundleID = [info objectForKey: @"CFBundleIdentifier"];
NSWorkspace *wp = [[NSWorkspace alloc] init];
NSString *app = [wp absolutePathForAppBundleWithIdentifier: bundleID];
const char *str = [[app substringToIndex: [app length] - [[app lastPathComponent] length]]] cStringUsingEncoding: NSASCIIStringEncoding];
return std::string( str );
}
精彩评论