使用xcode的c ++ app中文件的相对路径

时间:2011-10-30 00:22:58

标签: c++ xcode cocoa sdl

我正在尝试使用cocoa app加载文件,但应用程序无法找到该文件

我使用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 个答案:

答案 0 :(得分:1)

你可以使用objective-c ++,然后你有c ++和objective-c功能 要在便携式环境中使用objetive 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 :(得分:1)

如果您的代码是从主应用程序包运行的,那么您可以使用以下内容:

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 Programming Guide: Getting the Path to a Resource

另外,我不确定你的应用程序是如何“可可”的。具体来说,我不确定您是否已经有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 ++,但是2个主要的GUI框架是Carbon(基于C的HIToolbox)或Cocoa(基于Objective-C)。你知道你正在使用哪一个,或者你正在使用隐藏这些细节的另一个框架(它看起来像SDL)?

答案 2 :(得分:0)

您的意思是"./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()

编辑:

添加完整性。您可以使用找到的代码here将其基于可执行文件的路径。在所有现实中,几乎所有的Unix代码都基于主目录并回退到/ etc中的文件。这就是我的代码的大多数用户想要的(以及我想要的用户)。