问题
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 opengl/glut application.
回答1:
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.
回答2:
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.
回答3:
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 );
}
来源:https://stackoverflow.com/questions/7452076/mac-osx-c-app-cannot-find-a-file-fopen