web-dev-qa-db-ja.com

Xcode C ++で相対パスが機能しない

Xcodeで相対パスがどのように機能しないかを詳しく説明しているネット上の投稿は多数あります。相対パスが機能する場所にダウンロードしたXcodeテンプレートがありますが、その理由を理解できず、他のプロジェクトで複製することもできません。

まず、Xcode3.1でC++を使用しています。私はObjective-CもCocoa/Carbonフレームワークも使用しておらず、純粋なC++のみを使用しています。

他のXcodeテンプレートで機能するコードは次のとおりです。

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

この相対パスは、Windowsでも機能します。次のコマンドを実行すると、アプリケーションのフルパスへの絶対パスが表示されます。

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

/アプリケーション/ myApp

Xcode .appバンドルで動作する相対パスを取得するにはどうすればよいですか?

30
Brock Woolf

Googleを約5時間かけて、さまざまなことを試して、最終的に答えを見つけました。

#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人に感謝します、あなたの助けは最終的に私をこの答えを見つけるための正しい軌道に乗せたので、私はあなたの両方に投票しました。みんなありがとう!!!!

62
Brock Woolf

バイナリコードの現在の作業ディレクトリに依存しないでください。しないでください。 Mac、Windows、またはUnixでは、オペレーティングシステムまたはシェルを信頼して、設定したい場所に設定することはできません。

ストレートCの場合、dyld.hの_NSGetExecutablePathを使用して現在の実行可能ファイルへのパスを取得すると、そこから相対パスを取得できます。

実験しているだけで動作させたい場合は、Xcodeで[プロジェクト]> [アクティブな実行可能ファイルの編集]を選択すると、最初の作業ディレクトリをプロジェクトディレクトリ、実行可能ファイルの親ディレクトリ、または任意のディレクトリに設定できるパネルがあります。これは、テスト目的でのみ使用する必要があります。 Mac OSでは、実際のアプリを作成してFinderから起動すると、作業ディレクトリは/になります。また、Unixアプリの場合、作業ディレクトリが何であるかを制御することはできません。

12
cdespinosa

私の推測では、構築しているアプリの種類は、実行可能なアプリバンドルではなく、1回限りの実行可能ファイルです。一般に、OS XおよびUnixでは、リソースはドライブの絶対ルートからロードされます。これは、プロジェクトのルートからの相対パスである「ルート」のVisual C++の処理とは異なります。特にOS間(またはOSバージョン)の相対的なパスに依存しないでください。 Xcodeで作業ディレクトリを設定できますが、これはXcodeから起動されたアプリケーションにのみ影響します。 Finderのビルドディレクトリから実行する場合は、ドライブのルートに再度設定されます。

2
wisequark

相対パスとxcodeについてのコメントです。

最近、アプリにリソースフォルダーにコピーされるファイルがない場合、現在の作業ディレクトリが実際の.appのディレクトリに設定されていることに気付きました(例:myApp.appのレベル)

ただし、プロジェクトにファイルを追加し、それをアプリバンドルのResourcesフォルダーにコピーすると、cwdが.app内の3レベルの深さに設定されます。たとえば、myApp.app/Contents/MacOS/myAppのレベルで

Xcodeはあなたのために賢くしようとしているようで、アプリバンドルにリソースがない場合は、内部の実行可能ファイルレベルではなく、.appレベルでファイルをロードすることを想定しています。

これは、アプリがFinderから起動された場合でも持続します。したがって、相対パスを回避するもう1つの理由が考えられます。

0
user250691