Подтвердить что ты не робот

Относительные пути не работают в Xcode С++

В сети есть множество сообщений, в которых подробно описывается, как относительные пути не работают в Xcode. У меня есть шаблон Xcode, который я загрузил там, где работают относительные пути DO, однако я не смог понять, почему и не реплицировать его в других проектах.

Во-первых, я использую С++ в Xcode 3.1. Я не использую Objective-C, ни любые Cocoa/Carbon frameworks, просто чистые С++.

Вот код, который работает в моем другом шаблоне Xcode:

sound->LoadMusic( (std::string) "Resources/Audio/Pop.wav" );

Этот относительный путь работает для меня также в Windows. Выполнение следующей команды дает мне абсолютный путь к полному пути приложения:

std::cout << "Current directory is: " << getcwd( buffer, 1000) << "\n";

/Applications/MYAPP

Как мы можем получить относительные пути для работы в пакете Xcode.app?

4b9b3361

Ответ 1

Взял меня около 5 часов Google и попробовал разные вещи, чтобы НАКОНЕЦ найти ответ!

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

// ----------------------------------------------------------------------------
// 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);
    std::cout << "Current Path: " << path << std::endl;
#endif
// ----------------------------------------------------------------------------

Я добавил несколько дополнительных защитников, потому что это заставляет его компилировать только Apple (я разрабатываю кросс-платформу) и делает код более приятным.

Я благодарю других двух парней за ваши ответы, ваша помощь в конечном итоге заставила меня на правильном пути найти этот ответ, поэтому я проголосовал за вас обоих. Спасибо, ребята!!!!

Ответ 2

Не зависит от текущего рабочего каталога в двоичном коде. Только не надо. Вы не можете доверять операционной системе или оболочке, чтобы установить ее там, где вы ожидаете ее установки, на Mac, Windows или Unix.

Для прямого C используйте _NSGetExecutablePath в dyld.h, чтобы получить путь к вашему текущему исполняемому файлу, тогда вы можете перейти оттуда.

Если вы просто экспериментируете и хотите, чтобы он работал, в Xcode выберите Project > Edit Active Executable и там появится панель, в которой вы можете установить начальную рабочую директорию в каталог проекта, исполняемый родительский каталог или любой произвольный каталог. Это следует использовать только для целей тестирования. В Mac OS, когда вы пишете реальное приложение и запускаете его из Finder, рабочим каталогом является /. А для приложений Unix у вас нет никакого контроля над тем, чем является рабочий каталог.

Ответ 3

Мое предположение - это тип приложения, которое вы создаете, это одноразовый исполняемый файл, а не исполняемый пакет приложений. В ОС X и Unix в целом ресурсы загружаются из абсолютного корня диска, который отличается от обработки на Visual С++ "root", являющегося путем относительно корня проекта. Не полагайтесь на путь, когда-либо имеющий отношение к чему-либо, в частности, к ОС (или версии ОС, если на то пошло). Вы можете установить рабочий каталог в Xcode, но это повлияет только на приложения, запущенные с Xcode. Если вы должны были выполнить его из каталога сборки в Finder, он снова будет установлен в корень диска.

Ответ 4

Просто комментарий об относительных путях и xcode.

Недавно я заметил, что если ваше приложение не имеет файлов, которые будут скопированы в папку ресурсов, то текущий рабочий каталог будет установлен в фактическом .app - например, на уровне: myApp.app

Однако, если вы добавите файл в свой проект и скопируете его в папку "Ресурсы" вашего пакета приложений, он установит cwd на 3 уровня в пределах .app. например, на уровне myApp.app/Contents/MacOS/myApp

Кажется, xcode пытается быть умным для вас и предполагает, если у вас нет ресурсов в вашем комплекте приложений, тогда вы захотите загружать файлы на уровне .app, а не на уровне внутренних исполняемых файлов.

Это сохраняется, даже когда приложение запускается из Finder. Поэтому, возможно, еще одна причина избежать относительных путей.