Относительный путь для файлов в приложении c ++ с использованием xcode - PullRequest
2 голосов
/ 30 октября 2011

Я пытаюсь загрузить файл с приложением какао, но приложение не может найти файл

Я использую SDL_image, код:

SDL_Surface * surface = IMG_Load (file);

файл: "/Resources/cursor.png"

Я пытался использовать некоторые строки в Objective-C, но приложение не запускается, так как оно написано на c ++

Спасибо, Даниэль

Обновление:

Код загрузки текстуры:

GLuint CGLTexture::load_texture(const char* file, bool wrap)
{
SDL_Surface* surface = IMG_Load(file);

if (!surface) {
    printf("Error, probably the file isn't there :S");
    return 0;
}

GLuint texture;
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
SDL_PixelFormat *format = surface->format;

// select modulate to mix texture with color for shading
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

// when texture area is small, bilinear filter the closest mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                GL_LINEAR_MIPMAP_NEAREST );
// when texture area is large, bilinear filter the first mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// if wrap is true, the texture wraps over at the edges (repeat)
//       ... false, the texture ends at the edges (clamp)
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                wrap ? GL_REPEAT : GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                wrap ? GL_REPEAT : GL_CLAMP );

if (format->Amask)
{
    gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
                      surface->w, surface->h, GL_RGBA,GL_UNSIGNED_BYTE, surface->pixels);
}
else
{
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
                      surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
}
SDL_FreeSurface(surface);
return texture;
}

Я вызываю эту функцию так:

cursorTexture = CGLTexture::load_texture("/Resources/cursor.png",false);

Файлне найден, я думаю, что это где-то в комплекте приложения, но как я могу получить к нему доступ с помощью c ++?

Ответы [ 3 ]

1 голос
/ 30 октября 2011

Вы можете использовать Objective-C ++, тогда у вас есть функции C ++ и Objective-C.
Чтобы использовать объектив C в переносимой среде, используйте это:

header file:

std::string GetTextureFilename(const char *Name);

implementation file that ends with .mm and included only in mac:

std::string GetTextureFilename(const char *Name)
{
    return [[[NSBundle mainBundle]
                  pathForResource:
                      [NSString stringWithUTF8String: Name
                                              ofType: nil] toUTF8String];
}

source file that ends with .cpp and included only on other platforms:

std::string GetTextureFilename(const char *Name)
{
    return Name;
}
1 голос
/ 30 октября 2011

Если ваш код выполняется из основного пакета приложения, вы можете использовать следующее:

NSString *cursorImagePath = [[NSBundle mainBundle] 
             pathForResource:@"cursor" ofType:@"png"];

const char *cCursorImagePath = [cursorImagePath fileSystemRepresentation];

cursorTexture = CGLTexture::load_texture(cCursorImagePath, false);

(Примечание: измените расширение имени файла для всех файлов, в которых вы хотите использовать Objective-C, из.cpp до .mm).

NSBundle (или CFBundle) может использоваться для определения (полного) пути к ресурсам внутри пакета приложения.См. Руководство по программированию Bundle: получение пути к ресурсу .

Кроме того, я не уверен, насколько "Какао" является вашим приложением.В частности, я не уверен, что у вас уже есть NSAutoreleasePool на месте.Наблюдайте за выводом в Console.app или консоли отладки Xcode на наличие сообщений об ошибках в соответствии с __NSAutoreleaseNoPool() - just leaking.Если вы видите их, вам нужно будет окружить приведенный выше код следующим текстом:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// above code
[pool release];

Относительно "Нужно ли включать что-то, чтобы использовать этот код? Это приложение на C ++":

Да, вам нужно импортировать (и ссылаться на него, если вы этого еще не сделали):

#import <Foundation/Foundation.h>

(#import - умный Objective-C #include: он гарантирует, что этовключается только один раз).

Вы говорите, что ваше приложение написано на C ++, но две основные структуры GUI - это Carbon (на основе C HIToolbox) или Cocoa (на основе Objective-C).Знаете ли вы, какой из них вы используете, или вы используете другой фреймворк (похоже, SDL), который скрывает эти детали?

0 голосов
/ 30 октября 2011

Вы имеете в виду "./Resources/cursor.png"?

"/Resources/cursor.png" находится в корневой файловой системе

"./Resources/cursor.png" относительно рабочего каталога.

или вы можете сделать это относительно домашнего пути пользователя

#include <string>
#include <stdlib.h>
    std::string filename = getenv("HOME");
    filename += "/.ecf/employee.db";

Это не будет работать в ОС Unix, которые не заполняют переменную среды. Мне сказали, что OS X не делает. Независимо от того, почему это не помогает, вы можете использовать getpwuid() в этот момент.

редактирование:

Добавлено для полноты. Вы можете основать его на пути к исполняемому файлу, используя найденный код здесь . В действительности почти весь мой код Unix основывается на домашнем каталоге и резервном файле, найденном в / etc. Это то, что хотят большинство пользователей моего кода (и как пользователь, которого я хочу).

...