2013-09-09 4 views
4

У меня возникла странная проблема с доступом к файлам через SDL2 на Mac. Я использую XCode 4 в OS X Mountain Lion, и я использую SDL2 в качестве рамки. Я НЕ компилирую SDL2 из источника. Я добавил фреймворк к набору, а также файлы, которые мне нужно загрузить. Программа строит и отлично работает с XCode, но файлы не загружаются за пределы редактора (I.Е., если я дважды щелкните автономный файл .app, файлы не загружаются). Вот что мой .app пакет выглядит следующим образом:SDL2 Mac Обработка файлов

MyApp.app/ 
    Contents/ 
     Frameworks/ 
      SDL2.framework/ 
     MacOS/ 
      MyApp 
     Resources/ 
      Configure.txt 
      MyBMP.bmp 
     Info.plist 
     PkgInfo 

В моем коде C, я попытался это:

SDL_LoadBMP("MyApp.app/Contents/Resources/MyBMP.bmp"); 

Как только это:

SDL_LoadBMP("MyBMP.bmp"); 

И практически все между. Я также пытался получить доступ к текстовому файлу через:

FILE* data = fopen("MyApp.app/Contents/Resources/Configure.txt", "r"); 

и

FILE* data = fopen("Configure.txt", "r"); 

ни к какому успеху. В редакторе XCode работают только длинные абсолютные пути, но ничего, что я пробовал, работал в автономном .app.

Другие люди испытывают эту проблему? Я загружал файлы, когда использовал SDL 1.2, но по какой-то причине ничего не загружает SDL2. SDL2 делает что-то странное с активным каталогом во время инициализации?

------------- EDIT 1 -------------- Моя последняя попытка выяснить, что происходит использовал этот код:

#include "SDL2/SDL.h" 
#include "stdio.h" 
#include "stdlib.h" 

int main (int argc, char** argv){ 
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0) 
     return EXIT_FAILURE; 

    FILE* test = fopen("Test.txt", "w"); 

    if (!test) 
     return EXIT_FAILURE; 

    fprintf(test, "Let's see where this ends up..."); 
    fclose(test); 
    return EXIT_SUCCESS; 

    //The rest of my code, which shouldn't ever come into play... 
} 

При запуске из редактора XCode 4 это работает так, как ожидалось. В папке Debug, рядом с моим файлом .app, есть файл Test.txt, содержащий фразу «Давайте посмотрим, где это закончится ...». Однако при запуске, щелкнув автономное приложение, программа сразу заканчивается и текстовый файл не найден. Я проверил журналы, и он просто говорит, что программа вышла с кодом 1. Более тщательный анализ кажется, что fopen() не работает. Кто-нибудь имеет представление о том, что может происходить?

+0

Просто дикий удар в темноте, но вы пробовали: 'FILE * данные = Еореп ("../ Resources/Configure.txt", "г");' – Zammalad

+0

@ Zammalad Я пробовал это, и это не сработало. Я обновлю вопрос с недавними открытиями. – BrainSteel

ответ

3

Вы можете установить рабочий каталог в каталоге ресурсов в приложении пачке с помощью:

#include "CoreFoundation/CoreFoundation.h" 

char path[PATH_MAX]; 
CFURLRef res = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); 
CFURLGetFileSystemRepresentation(res, TRUE, (UInt8 *)path, PATH_MAX) 
CFRelease(res); 
chdir(path); 

, которые вы можете обернуть между #ifdef __APPLE__ и #endif для перекрестной совместимости платформы.

+0

Это абсолютно трюк! Спасибо огромное! Где я могу найти документы для этих функций, чтобы понять, что происходит лучше? – BrainSteel

+0

https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html – Simon

0

Скачать библиотеку SFML для ResourcePath.hpp или получить его из https://github.com/Malaxiz/Third/blob/network/Fifth/ResourcePath.hpp https://github.com/Malaxiz/Third/blob/network/Fifth/ResourcePath.mm

#ifdef __APPLE__ 
#include "CoreFoundation/CoreFoundation.h" 
#include "ResourcePath.hpp" 
#endif 

void CGame::_initRelativePaths() { 
// ---------------------------------------------------------------------------- 
// This makes relative paths work in C++ in Xcode by changing directory to the Resources folder inside the .app bundle 
#ifdef __APPLE__ 
    CFBundleRef mainBundle = CFBundleGetMainBundle(); 
    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); 
    char path[PATH_MAX]; 
    if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) 
    { 
     // error! 
    } 
    CFRelease(resourcesURL); 

    chdir(path); 
    #endif 
    // --------------------------------------------------------------------------- - 
} 

запустить функцию в инициализации.

Ссылка: https://github.com/Malaxiz/Third/blob/network/Fifth/CGame.cpp#L191