【发布时间】:2014-12-04 07:41:02
【问题描述】:
过去一年我一直在编写游戏,我正在移植到 Mac。
我已根据:http://blog.davidecoppola.com/2013/08/22/how-to-set-up-a-sdl-2-project-for-os-x-in-xcode-4/ 进行了所有设置。我已经更改了一些步骤以补偿版本(5)。
在我的代码中,我使用 tinyXML 在资产文件夹中加载 .xml 文件。这在 Windows 和 linux 上完美运行,但是,在 Mac 中我遇到了一些问题。这是行:
Doc.LoadFile(DataPath);
Doc 是 tinyxml2::XMLDocument 类型,DataPath 通常是“assets/Data.xml”,在 Mac 中我将该行硬编码到“DataPath”的位置。
在 IDE 中运行代码时,我没有遇到任何问题,并且我的游戏可以像在所有其他平台上一样运行,但是,在运行 .app 文件(位于 gameMac/Build/Products/Debug 中)时,它会崩溃启动后。 Assets 文件夹也位于此位置。
这是崩溃后 Mac 向我抛出的错误:
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
(请注意,gameMac 不是我项目的名称,由于保密协议,我已更改该详细信息)。
正如我在这里所指出的,加载我的数据DataLoader::load(params) 的相同方法会导致崩溃。这让我相信我的资产文件夹没有被加载到我的 .app 文件中。
通过这个我尝试编辑构建阶段,Copy Bundle Resources 这并没有改变问题。然后我尝试创建一个新的构建阶段Copy Files 并将其设置为Resources,这也失败了。然后我通过将Copy Files 设置为Product Directory 进行了实验;这会将资产文件夹复制到构建文件夹,但 .app 文件仍然不会加载到资产中。
我错过了什么吗?一些 XCode 兽医可以在这里帮助我吗,过去几天我一直在尝试解决这个问题。谢谢。
http://pastebin.com/Xq4Hxh4d(这是我上面提到的 DataLoader 的顶部。编辑:在我的 nullptr 返回检查中添加,是的,如果失败则返回 true)。
P.S 我只能给出我的代码的sn-ps,我已经给出了我认为最有可能的问题,资源加载:)
完整的崩溃报告在下面的 cmets 中。
修复,感谢 Brad Allred 的帮助:
资源位于 .app 文件中,特别是 {Application}/Contents/Resources ;就我而言,我想访问资产中的文件。我做了一个构建阶段,将数据复制到资源文件夹,使我的目录为 {Application}/Contents/Resources/Assets/../。使用 SDL_GetBasePath 我可以创建一个字符串,它是从基本目录到 Resources 文件夹的绝对路径。
代码如下:
if(Doc.LoadFile("assets/Data.xml"))
{
std::string path = (std::string)SDL_GetBasePath() + "assets/Data.xml";
if(Doc.LoadFile(path.c_str()))
{
return false;
}
}
我连接基本路径 + 我需要的任何数据,并将 .c_str() 版本传递给 tinyXML。如果我找到更好/更干净的版本,我一定会在这里更新。
【问题讨论】:
-
您是否正在尝试加载文件,并且不检查
NULL指针返回?可能发生的原因是因为您在 Xcode 中运行它时的当前目录可能是您在 Xcode 之外运行程序的另一个目录。 -
@JoachimPileborg pastebin sn-p 比当前版本稍旧。我还没有更新我的存储库。我确实检查了 nullptr 返回,在 IDE 中一切正常。如果是这样,那么我该如何将我的资产文件夹链接到我的应用程序文件?编辑:我在我的 nullptr 检查中添加了。
-
拥有完整崩溃报告(或至少
Exception Type)和控制台输出会很有用。 -
@BradAllred 这是完整的崩溃报告:pastebin.com/Hc3m3XGX