2012-04-20 9 views
8

जब मैं कक्षा के इंटरफेस के ऊपर हेडर फ़ाइल में सी फ़ंक्शन को परिभाषित करने का प्रयास करता हूं तो मुझे हमेशा एक बिल्ड त्रुटि मिलती है।मैं हेडर फ़ाइल में सादे सी फ़ंक्शंस को परिभाषित क्यों नहीं कर सकता?

लेकिन जब मैं कार्यान्वयन फ़ाइल में ऐसा करता हूं और शीर्षलेख में एक घोषणा देता हूं। चीजें काम करते हैं।

मैं जानना चाहता था, क्यों यह इतना है क्योंकि मैं हेडर फाइल में enums, structs, निरंतर NSStrings परिभाषित है, इसलिए है सी कार्यों नहीं क्यों?

उत्तर

14

यह सी लिंकर (या लिंक संपादक) काम करता है जिस तरह से करना है। जब सी कंपाइलर फ़ंक्शन परिभाषा में आता है, तो वह उस असेंबलर कोड को तैयार करता है जो उस कार्य को कार्यान्वित करता है और इसे प्रतीक के साथ चिह्नित करता है जो लिंकर से कहता है "यह वह जगह है जहां इस नाम के साथ कार्य शुरू होता है"। प्रतीक आमतौर पर फ़ंक्शन नाम के बाद अंडरस्कोर के साथ नामित किया जाता है, उदा। _printf

आप एक हेडर फाइल में समारोह है, तो हर .c या .m फ़ाइल आयात करता है कि इस शीर्ष लेख समारोह संकलन होगा, और एक ही प्रतीक फेंकना संकलक का कारण होगा निर्धारित करते हैं। लिंकर को केवल प्रत्येक प्रतीक का एक उदाहरण मिलना है, इसलिए यह एक त्रुटि है।

यह #include गार्ड के अस्तित्व से संबंधित नहीं है, या #include के बजाय #import का उपयोग करने के लिए है। सी कंपाइलर व्यक्तिगत अनुवाद इकाइयों पर काम करता है - जिसके द्वारा इसका अर्थ व्यक्तिगत स्रोत फ़ाइलों का होता है। प्रीप्रोसेसर रणनीतियों में आपको एक ही शीर्ष फ़ाइल फ़ाइल को एक ही स्रोत फ़ाइल में दो बार रोक दिया जाता है, लेकिन कई फ़ाइलों में गतिविधियों को समन्वयित करने के लिए कुछ भी नहीं करता है। इसका अर्थ यह है कि अलग-अलग स्रोत फ़ाइलों में एक ही शीर्षलेख शामिल करना मान्य है: इसका अर्थ यह भी है कि जब आप विभिन्न फ़ाइलों को संकलित करते हैं, तो वे (वैध रूप से) एक ही प्रतीक को शामिल कर सकते हैं।

यह इन फ़ाइलों को एक साथ रखने के लिए लिंक संपादक का काम है, संकलन समय पर अज्ञात प्रतीकों के किसी भी संदर्भ को हल करना। यदि आप ऑब्जेक्ट्स (संकलित और एकत्रित अनुवाद इकाइयों का नाम) लिंक करने का प्रयास करते हैं, जिसमें समान संग्रह, साझा लाइब्रेरी या निष्पादन योग्य में एक ही प्रतीक है, तो आपको वह त्रुटि मिल जाएगी जो आप यहां देख रहे हैं।

समाधान:

  • शीर्षक में समारोह को परिभाषित नहीं है, सिर्फ वहाँ यह घोषणा करते हैं और एक कार्यान्वयन फ़ाइल में परिभाषित; जैसा कि आप पहले से ही यह काम पाया है।
  • शीर्षलेख में फ़ंक्शन को परिभाषित करें, लेकिन केवल उस कोड को अपने कोड में एक ही स्थान पर शामिल करें। यह डिजाइन कारणों के लिए अक्सर अस्वीकार्य है।
  • संशोधक inline के साथ शीर्षलेख में फ़ंक्शन को परिभाषित करें। इनलाइन फ़ंक्शंस को संकलक द्वारा केवल उस फ़ंक्शन में कॉपी किया जाता है जहां उन्हें कॉल किया जाता है, इसलिए उनके लिए एक लिंकर प्रतीक कभी उत्सर्जित नहीं होता है। इसका अपना व्यापार-बंद है कि आप may wish to read more about
+0

shuldn't #import (# शामिल करने के बजाय) केवल एक बार एक फ़ाइल शामिल हैं? और .. आप गार्ड शामिल कर सकते हैं (#ifndef MYFILE_H #define MYFILE_H ... #endif) – Francesco

+1

प्रश्न @ फ्रांसेस्को के लिए धन्यवाद, मैंने ऊपर एक उत्तर शामिल किया है (लघु संस्करण यह है कि प्रीप्रोसेसर गार्ड रुकेंगे नहीं आपको लिंक त्रुटियां मिल रही हैं)। –

+0

लेकिन क्या हम सी कार्यों की परिभाषाओं या घोषणाओं की बात कर रहे हैं? क्योंकि .. मैंने एक .h फ़ाइल में फ़ंक्शन परिभाषा के साथ प्रयास किया है, और फ़ाइल को दो बार शामिल किया है। यदि मैं # शामिल करता हूं तो मुझे फ़ंक्शन का "पुनर्वितरण" मिलता है। अगर मैं # आयात या गार्ड का उपयोग करता हूं (प्रत्येक .h फ़ाइल में) मुझे कोई त्रुटि नहीं मिलती है ... – Francesco

संबंधित मुद्दे

 संबंधित मुद्दे