2013-09-21 5 views
5

में यादृच्छिक डुप्लिकेट प्रतीकों मैं एक्सकोड 4.6.3 में एक सी ++ प्रोजेक्ट बनाने की कोशिश कर रहा हूं।एक्सकोड (सी ++)

अपने प्रोजेक्ट (एक बहुत ही सरल ओपन खेल की शुरुआत) मैं दो फ़ाइलों में:

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"); 
} 

यहां ut.h उपयोग :: लोडटेक्चर फ़ंक्शन को परिभाषित करता है।

दो फाइलें हैं जिनमें textures.h शामिल हैं। पहला (main.cpp) लोड() फ़ंक्शन को प्रारंभिकरण के हिस्से के रूप में कॉल करता है और गंदगी चर का उपयोग Soil.png बनावट को बांधने के लिए करता है। दूसरा (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 का उपयोग करते हैं, और मैंने "गंदगी" और ऐसे कार्यों के लिए वर्कस्पेस में खोज की है, और कोई अन्य परिभाषा नहीं है। मेरे अन्य शीर्षलेख ठीक काम करते हैं, यहां तक ​​कि वे कई बार शामिल होते हैं। मैंने अलग-अलग कीवर्ड के साथ कई बार इस समस्या को गुमराह किया है, और अन्य समान प्रश्नों पर एक नज़र डाली है, लेकिन मुझे मिली सभी this SO question थी।

मुझे एक्सकोड में पहले "यादृच्छिक" त्रुटियों का सामना करना पड़ा - उदाहरण के लिए, एक प्रोजेक्ट एक गतिशील लाइब्रेरी का उपयोग करने की कोशिश करता रहा जिसे मैंने हटा दिया था और एक स्थिर स्थान के साथ बदल दिया था। त्रुटि तब भी रुक गई जब मैंने एक नई परियोजना बनाई। यह टर्मिनल से मैन्युअल रूप से संकलित जब काम किया।

मुझे क्या याद आ रही है?

उत्तर

5

#pragma once एक हेडर फ़ाइल को कई बार शामिल नहीं किया जाता है।

यह एक ही फ़ाइल फ़ाइल को को एक फ़ाइल को संकलित करते समय को संकलित करते समय रोकता है। आपके पास (कम से कम) तीन फाइलें हैं, इसलिए आप एक ही चर को 3 बार घोषित कर रहे हैं।

एक शीर्षलेख फ़ाइल में चर परिभाषाएं न डालें। ऐसा करने के बजाय

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


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

के रूप में आप (बशर्ते कि वे सभी एक जैसे हैं) चाहते हैं तो आप एक चर के रूप में कई घोषणाओं हो सकता है, इसलिए यह एक हेडर फाइल में घोषणाओं डाल करने के लिए ठीक है, तुम ठीक एक चर परिभाषा होनी चाहिए, इसलिए आप इसे एक .cpp फ़ाइल में डालते हैं।

याद रखने की कुंजी यह है कि प्रत्येक .cpp फ़ाइल को हर दूसरे .cpp फ़ाइल से पूरी तरह से स्वतंत्र रूप से संकलित किया जाता है, इसे अलग संकलन कहा जाता है। तो आपका विचार है कि #pragma once एक हेडर फ़ाइल को एक .cpp फ़ाइल द्वारा शामिल करने से रोक देगा क्योंकि यह किसी अन्य .cpp फ़ाइल में शामिल किया गया था बस काम नहीं करता है। आप इसे गलत समझने वाले पहले व्यक्ति नहीं हैं।

+0

मैंने #ifndef #define #endif के लिए एक बार #pragma को प्रतिस्थापित करने का प्रयास किया है जो प्रारंभ में एक्सकोड बनाता है, और यह अभी भी काम नहीं करता है ... – qxz

+0

अच्छा #ifndef ...ठीक उसी तरह #pragma के समान काम करता है, और ऐसा करने में विफल रहता है जो आपको लगता है कि इसे उसी कारण से करना चाहिए। जो मैंने पोस्ट किया वह एक टिप नहीं है, वैश्विक चर का उपयोग करने का यह सही तरीका है। – john

+0

#pragma का उपयोग एक बार या #ifndef का उपयोग करना बंद न करें ... यह सिर्फ आपके द्वारा किए गए कार्यों से अलग समस्या हल करता है। – john