Относительные пути не работают в 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?
Ответы
Ответ 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. Поэтому, возможно, еще одна причина избежать относительных путей.