简体   繁体   中英

Xcode 5 C++ SDL app not loading outside of XCode IDE

I've been coding a game for the past year, I'm in the process of porting to Mac.

I've set everything up according to: http://blog.davidecoppola.com/2013/08/22/how-to-set-up-a-sdl-2-project-for-os-x-in-xcode-4/ . I have changed some of the steps to compensate for the version (5).

In my code I use tinyXML to load a .xml file within an assets folder. This works perfectly on windows and linux, however, in Mac I experience some issues. Here's the line:

Doc.LoadFile(DataPath);

Doc is a tinyxml2::XMLDocument type, and the DataPath is usually "assets/Data.xml", in Mac I hard-coded that line into the place of "DataPath".

When running the code within the IDE I experience no issues and my game comes up and plays like it does on all other platforms, however, when running the .app file (Located in gameMac/Build/Products/Debug) it crashes right after starting up. The Assets folder is also located in this location.

Here's the error Mac throws at me after the crash:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   gameMac                        0x000c1525 tinyxml2::XMLNode::FirstChildElement(char const*) const + 21
1   gameMac                        0x000d1954 tinyxml2::XMLNode::FirstChildElement(char const*) + 36
2   gameMac                        0x000d04d5 DataLoader::load(char const*, ID_Data, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) + 197
3   gameMac                        0x000a5849 MapHandler::MapHandler(std::__1::shared_ptr<gameData>) + 1177
4   gameMac                        0x000a539e MapHandler::MapHandler(std::__1::shared_ptr<gameData>) + 30
5   gameMac                        0x000b7eb8 splay::splay(std::__1::shared_ptr<gameData>) + 1592
6   gameMac                        0x000b786e splay::splay(std::__1::shared_ptr<gameData>) + 30
7   gameMac                        0x000ee3f9 std::__1::shared_ptr<splay> std::__1::shared_ptr<splay>::make_shared<std::__1::shared_ptr<gameData>&>(std::__1::shared_ptr<gameData>&&&) + 1849
8   gameMac                        0x000ebc7c stateHandlerGen::stateHandlerGen(std::__1::shared_ptr<gameData>) + 236
9   gameMac                        0x000ebb7e stateHandlerGen::stateHandlerGen(std::__1::shared_ptr<gameData>) + 30
10  gameMac                        0x000e7a89 game::init(char const*, int, int, int, int, bool) + 1545
11  gameMac                        0x000be8c4 main + 516
12  libdyld.dylib                       0x91b3c725 start + 1

(Please note that gameMac is not the name of my project, I have changed that detail due to an NDA).

As I've noted here, the same method that loads my data DataLoader::load(params) is giving the crash. This leads me to believe that my assets folder is not being loaded into my .app file.

Through this I attempted to edit a Build Phase, Copy Bundle Resources this did not change the issue. I then attempted to make a New Build Phase Copy Files and set it to Resources , this also failed. I then experimented by setting the Copy Files to Product Directory ; this copied the assets folder to the build folder, but the .app file still won't load in the assets.

Did I miss something? Could some XCode vets help me out here, I've attempted to fix this for the past few days. Thanks.

http://pastebin.com/Xq4Hxh4d (Here's the top of my DataLoader as mentioned above. EDIT: Added in my check for nullptr return, yes, it returns true if failed).

PS I can only give out snippets of my code, I have given what I feel is most likely the problem, resource loading :)

The full crash report is in the comments below.

The fix, thanks to the help from Brad Allred:

The resources are located within the .app file, specifically {Application}/Contents/Resources ; in my case I wanted to access a file within assets. I did a build phase to copy the data to the resources folder, making my directory {Application}/Contents/Resources/Assets/../. Using SDL_GetBasePath I'm able to create a string which is the absolute path from your base directory up to the Resources folder.

Here's the code:

if(Doc.LoadFile("assets/Data.xml"))
{
    std::string path = (std::string)SDL_GetBasePath() + "assets/Data.xml";
    if(Doc.LoadFile(path.c_str()))
    {
        return false;
    }
}

I concat the base path + whatever data I need, and pass the .c_str() version to tinyXML. If I find a better/cleaner version I'll be sure to update it here.

your crash report tells you the line number in your code that is crashing ( tinyxml2.cpp:745 ). at Probably your assets are not where the app expects them to be or doesnt have permission. examining your DataPath to see where its trying to load should get you started.

It seems like maybe you are mistakenly assuming that you can use a relative path and get assets relative to the app bundle; you can't do that.

Since you are using SDL, why not use the SDL API (see SDL_GetBasePath ) to get resource paths so that you can store your assets properly inside your app bundle in the Resources directory?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM