2009-02-05 13 views
30

Hay numerosas publicaciones en la red que detallan cómo las rutas relativas no funcionan en Xcode. Tengo una plantilla de Xcode que descargué donde funcionan las rutas relativas. Sin embargo, no he podido averiguar por qué ni replicarla en otros proyectos.Las rutas relativas no funcionan en Xcode C++

En primer lugar, estoy usando C++ en Xcode 3.1. No estoy usando Objective-C, ni ningún framework de Cocoa/Carbon, solo C++ puro.

Este es el código que funciona en mi otra plantilla de Xcode:

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

Esta ruta relativa funciona para mí también en Windows. Ejecutando el siguiente comando me da una ruta absoluta de ruta completa de la aplicación:

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

/Aplicaciones/myApp

¿Cómo podemos obtener las rutas relativas para trabajar en un paquete de Xcode .app?

+1

Gracias por esto - He estado golpeando mi cabeza contra la pared durante horas tratando de hacer que esto funcione en mi propio código multiplataforma. – JimDaniel

+0

Claro, no hay problema. Me llevó mucho tiempo resolver esto. Me alegro de que podría ayudar a alguien más. Ah, y usted puede votar mi pregunta/respuesta si le gusta: D –

Respuesta

61

Me tomó alrededor de 5 horas de Google e intenté diferentes cosas para FINALMENTE encontrar la respuesta.

#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 
// ---------------------------------------------------------------------------- 

He tirado un poco de sobrepeso incluyen guardias, porque esto hace que sea solamente la compilación de Apple (que desarrollo multiplataforma) y hace que el código más agradable.

Agradezco a los otros 2 hombres por sus respuestas, su ayuda finalmente me puso en el camino correcto para encontrar esta respuesta, así que les he votado a los dos. ¡¡¡¡Gracias chicos!!!!

+8

No tienes idea de cuánto ayuda esto. ¡Gracias por publicarlo! – AboutRuby

+1

¡Agradable! ¡Esto me salvó un montón de dolor de cabeza! – goatlinks

+5

símbolos no definidos para la arquitectura i386: "_CFBundleCopyResourcesDirectoryURL", se hace referencia a: jugador :: jugador() en jugador-1308A7B7A421D47D.o "_CFBundleGetMainBundle", se hace referencia a: jugador :: jugador() en jugador-1308A7B7A421D47D.o "_CFRelease", hace referencia a partir de: jugador :: jugador() en jugador-1308A7B7A421D47D.o "_CFURLGetFileSystemRepresentation", hace referencia a partir de: jugador :: jugador() en el reproductor de LD-1308A7B7A421D47D.o : símbolo (s) que no se encuentra para la arquitectura i386 –

12

No dependa del directorio de trabajo actual en código binario. Simplemente no lo hagas No puede confiar en que el sistema operativo o el shell lo configuren donde espera que se configure, en Mac, Windows o Unix.

Para C recta, use _NSGetExecutablePath en dyld.h para obtener la ruta al archivo ejecutable actual, luego puede ir relativo desde allí.

Si solo está experimentando y quiere que funcione, en Xcode elija Proyecto> Editar ejecutable activo, y hay un panel allí en el que puede establecer el directorio de trabajo inicial en el directorio del proyecto, el directorio principal del ejecutable o cualquier directorio arbitrario. Esto solo debe usarse con fines de prueba. En Mac OS, cuando escribes una aplicación real y la inicias desde Finder, el directorio de trabajo es /. Y para las aplicaciones de Unix no tiene ningún control sobre qué es el directorio de trabajo.

+0

Gracias por sus comentarios cdespinosa, estoy tratando de acceder a los recursos dentro del paquete myApp.app. Lo que dijiste sobre la edición del ejecutable activo funciona, sin embargo, tan pronto como se mueve myApp.app, ya no funciona, ya que no es una ruta relativa, sino absoluta. –

+0

Al final estoy intentando acceder a los recursos DENTRO del paquete .app . Esto ES POSIBLE, tengo otra plantilla de proyecto Xcode donde las rutas relativas SI funcionan, sin embargo, no hay un código en la plantilla. Funciona por defecto. La .app compilada de esta plantilla se puede mover a otra parte y las rutas siguen funcionando –

+0

Olvidé mencionar esto antes. Estoy haciendo chdir ((const char *) argv [0]), pero no cambia el directorio actual sin importar lo que haga. hmm –

2

Supongo que el tipo de aplicación que está compilando es un ejecutable único en vez de ser un conjunto de aplicaciones ejecutables. En OS X y Unixes en general, los recursos se cargan desde la raíz absoluta de la unidad, que es diferente al tratamiento de Visual C++ de "raíz" que es la ruta relativa a la raíz del proyecto. No confíe en que la ruta sea relativa a nada en particular en todos los SO (o versiones de SO para el caso). Puede establecer un directorio de trabajo en Xcode, pero eso solo afectará las aplicaciones lanzadas desde Xcode. Si tuviera que ejecutarlo desde el directorio de compilación en Finder, una vez más se establecería en la raíz de la unidad.

+0

No, él está tratando de usar el sistema .app estándar de OSX, donde debajo de .app tiene/Contents, luego debajo de/MacOS y/Resources. Definitivamente NO es relativo a la raíz absoluta del disco en ninguna circunstancia. La Mac puede ser unix, pero el sistema es más parecido a chroot jail (* tipo de *) que una aplicación de tipo/usr/bin/ejecutable estándar que verá en Linux y en unixes tradicionales. – Shayne

0

Solo un comentario sobre rutas relativas y xcode.

Hace poco noté que si su aplicación no tiene archivos que se copiarían en la carpeta de recursos, el directorio de trabajo actual está configurado para ser el de la .app real, por ejemplo, en el nivel de: myApp.aplicación

Sin embargo, si agrega un archivo a su proyecto y lo copia a la carpeta de Recursos de su paquete de aplicaciones establece que el cwd tenga 3 niveles de profundidad dentro de .app. por ejemplo, en el nivel de myApp.app/Contents/MacOS/myApp

Parece que xcode intenta ser inteligente para usted y asume que si no tiene recursos en el paquete de su aplicación, entonces le gustaría cargar los archivos a. nivel de aplicación y no el nivel de ejecutables internos.

Esto persiste incluso cuando la aplicación se inicia desde el Finder. Entonces quizás otra razón para evitar caminos relativos.

Cuestiones relacionadas