5

Xcode 4.6.3 で C++ プロジェクトをビルドしようとしています。

私のプロジェクト (非常に単純な OpenGL ゲームの始まり) には、次の 2 つのファイルがあります。

textures.h:

#pragma once

#include <GLUT/GLUT.h>

void load(); // load textures

GLuint dirt, water; // variables to store texture handles

textures.cpp:

#include "textures.h"

#include "util.h"

void textures::load() {
    dirt = util::loadTexture("/Some/Path/Soil.png");
    water = util::loadTexture("/Some/Path/Water_fresh.png");
}

ここで、util.h は util::loadTexture 関数を定義しています。

textures.h を含む 2 つのファイルがあります。最初の (main.cpp) は、初期化の一部として load() 関数を呼び出し、dirt 変数にアクセスして、Soil.png テクスチャをバインドします。2 番目 (Chunk.cpp) には textures.h が含まれていますが、実際にはまだそこから何もアクセスしていません。

プロジェクトをビルドしようとすると、次のエラーが表示されます。

duplicate symbol _dirt in:
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/Chunk.o
duplicate symbol _water in:
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/Chunk.o
duplicate symbol _dirt in:
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/textures.o
duplicate symbol _water in:
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/textures.o
ld: 4 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

これは、どこかに重複があるか、ヘッダーが複数含まれていることを意味すると理解しています。しかし、私のヘッダーはすべて を使用#pragma onceしており、ワークスペースで「汚れ」などを検索しましたが、他の定義はありません。私の他のヘッダーは、複数回含まれているヘッダーでも問題なく動作します。この問題をさまざまなキーワードで何度もグーグル検索し、他の同様の質問を調べましたが、見つかったのはこの SO questionだけでした。

Xcode で他の「ランダムな」エラーに遭遇したことがあります。新しいプロジェクトを作成しても、エラーは残りました。ターミナルから手動でコンパイルすると機能しました。

私は何が欠けていますか?

4

1 に答える 1

5

#pragma once複数回インクルードされるヘッダー ファイルを停止しません。

1 つのファイルをコンパイルするときに、ヘッダー ファイルが複数回インクルードされるのを防ぎます。(少なくとも) 3 つのファイルがあるため、同じ変数を 3 回宣言しています。

ヘッダー ファイルに変数定義を入れないでください。代わりにこれを行う

// textures.h
extern GLuint dirt, water; // variable declarations


// textures.cpp
GLuint dirt, water; // variable definitions

必要なだけ変数の宣言を行うことができます (それらがすべて同一である場合)。宣言をヘッダー ファイルに入れても問題ありません。変数定義は 1 つだけ必要なので、それを .cpp ファイルに入れます。

覚えておくべき重要な点は、すべての .cpp ファイルが他のすべての .cpp ファイルとは完全に独立してコンパイルされることです。これは個別コンパイルと呼ばれます。したがって#pragma once、別の .cpp ファイルに含まれていたという理由だけで、ヘッダー ファイルが 1 つの .cpp ファイルに含まれないようにするという考えは機能しません。これを誤解したのはあなたが初めてではありません。

于 2013-09-21T06:19:32.267 に答える