2011-03-30 14 views
6

मुझे अभी एक समस्या है जो मुझे भ्रमित कर रही है: मेरे पास सी ++ में लिखे गए सॉफ़्टवेयर का टुकड़ा है और सी में लाइब्रेरी के खिलाफ लिंक हैं I में हेडर क्लासेस का उपयोग करना शामिल है सामान्यजीसीसी अनुकूलन परिणाम रनटाइम पर "अपरिभाषित प्रतीक" में परिणाम

extern "C" { 
    #include <libheader.h> 
} 

जब तक मैं जीसीसी के अनुकूलन का उपयोग नहीं करता तब तक सब कुछ ठीक काम करता है। एक बार जब मैं -O1 चालू करता हूं, इस प्रकार रनटाइम के दौरान पहला ऑप्टिमाइज़ेशन स्तर मुझे इस लाइब्रेरी के प्रतीक के लिए "अपरिभाषित प्रतीक" त्रुटि मिलती है। हालांकि, नाम नाम mangling के माध्यम से चला गया है जो extern "C" के अक्षम कारण होना चाहिए।

इस मामले में प्रश्न में प्रतीक को कॉल करने वाले फ़ंक्शन को रेखांकित किया गया है। प्रयुक्त कंपाइलर जीसीसी 4.4.3 है।

मैं ईमानदारी से यह भी नहीं जानता कि क्या खोजना है, इसलिए यदि आप में से कोई मुझे इस व्यवहार के लिए कुछ कारण दे सकता है तो मैं वास्तव में आभारी रहूंगा।

आपके समर्थन के लिए धन्यवाद।

+0

क्या आप इनलाइन को हटा सकते हैं (यानी फ़ंक्शन को इनलाइन नहीं करते हैं) और देखें कि यह काम करना शुरू कर रहा है या नहीं? – sashoalm

+1

वैकल्पिक रूप से @ सैटून के सुझाव के लिए, क्या आप इनलाइन फ़ंक्शन को एक C++ फ़ंक्शन कॉल कर सकते हैं जो सी फ़ंक्शन को लपेटता है, और देखें कि क्या यह काम करना शुरू कर देता है? –

+0

आपके उत्तर के लिए धन्यवाद! मैंने दोनों सुझावों की कोशिश की, हालांकि, प्रतीक अभी भी नहीं मिला है। – Thilo

उत्तर

1

क्या यह संभव है कि शीर्ष लेख बुला इनलाइन समारोह को परिभाषित करता है कि बिना पुस्तकालय के हेडर extern "C" आवरण शामिल है, और अन्य सभी स्थानों आवरण लाइनों उपयोग किया जाता है?

क्या आपने -O2 जैसे अन्य स्तरों को आजमाया है?

क्या आपने अपने फ़ंक्शन को अनलाइन करने का प्रयास किया था?

+0

विचारों के लिए धन्यवाद। हां, सही फ़ाइल का शीर्षलेख निश्चित रूप से 'बाहरी "सी" रैपर का उपयोग करता है। -ओ 2 और -ओ 3 का एक ही प्रभाव है। जैसा कि ऊपर बताया गया है, इनलाइन को हटाने से या तो मदद नहीं मिलती है। – Thilo

+0

@ थिलो विशेष रूप से, आपने इनलाइन को हटा दिया और फ़ंक्शन को हेडर से स्रोत फ़ाइल में ले जाया ताकि संकलक स्वचालित रूप से इनलाइन करने का निर्णय नहीं ले सके? –

+0

अरग ... स्पष्टीकरण के लिए धन्यवाद। पहले उल्लिखित फ़ंक्शन को स्रोत फ़ाइल में स्थानांतरित करने के लिए भूल गए। यह समस्या हल करता है। हालांकि, परिणाम वास्तव में सुरुचिपूर्ण नहीं है, क्योंकि इनलाइन फ़ंक्शन को काफी तेज़ किया जा सकता है। – Thilo

3

यदि आपके पास कोई फ़ंक्शन है जिसे परिभाषित नहीं किया गया है, लेकिन इनलाइन किए जाने पर परिभाषित नहीं किया गया है, तो समस्या को परिभाषित करने के लिए बहुत सरल होना चाहिए।

आपने अपनी शीर्षलेख फ़ाइल को शामिल किए बिना कहीं भी फ़ंक्शन का उपयोग किया है।

इस फ़ंक्शन को कॉल करने वाली सभी फ़ाइलों की समीक्षा करें और सुनिश्चित करें कि हेडर शामिल है।

0

extern "C" {...} के साथ एक सी हेडर लपेटना हमेशा काम नहीं करता है; आम तौर पर, हेडर को दोनों भाषाओं के साथ काम करने के लिए दोनों भाषाओं के साथ काम करने के लिए डिज़ाइन करने की आवश्यकता होती है।

इस मामले में, अधिक जानकारी के बिना, यह मुश्किल कहने के लिए वास्तव में क्या है हो रहा, लेकिनinline कीवर्ड सी में और में सी ++ अलग बातें मतलब है; मैं इस तरीके से काम करने के लिए inline फ़ंक्शंस वाले शीर्षलेख की अपेक्षा नहीं करूंगा। (हाथ के बाहर, मैं लक्षण आप हो रही है उम्मीद करेंगे नहीं, लेकिन वे विशेष रूप से मुझे या तो आश्चर्य नहीं है ।)

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

उसमें असफल होने पर इस संभाल करने के लिए सही तरीका अपने स्वयं के सी कोड है, जो शीर्ष लेख भी शामिल है और आप जरूरत कार्यों के सभी लपेटता लिखने के लिए, और इस सी कोड है, जो बनाया गया है के लिए अपने स्वयं के हैडर लिखना है दोनों भाषाओं में शामिल किया जाना चाहिए। जो है, मैं स्वीकार करूंगा, बहुत सारे काम; आपूर्तिकर्ता को अपना काम करने के बजाय के लिए आधा करने के बजाय प्राप्त करें।

4

आप कहते हैं कि आप फ़ाइल को extern "C" ब्लॉक में शामिल कर रहे हैं, लेकिन लिंकर जिस प्रतीक को ढूंढ रहा है वह नाम-उलझन में है।

एक संकेत है कि libheader.h भी extern "C" ब्लॉक के बाहर शामिल किया जा रहा है है कि (वे शामिल अंदर extern "C" ब्लॉक शायद libheader.h में गार्ड में शामिल होने के कारण एक nop है)।

अन्य तरीकों की तलाश करें जो libheader.h शामिल हो रहे हैं। जीसीसी का -E और/या विभिन्न -M विकल्प इससे मदद कर सकते हैं या नहीं भी। या (यदि केवल एक परीक्षण के लिए) libheader.h अंदर extern "C" ब्लॉक को स्थानांतरित:

// at start of libheader.h: 
#ifdef __cplusplus 
extern "C" { 
#endif 

/* existing contents of libheader.h */ 
// ... 

// at end of libheader.h: 
#ifdef __cplusplus 
} 
#endif 

ध्यान दें कि लिंकेज विनिर्देशों कर सकते हैं घोंसला, आप #include स्थलों पर मौजूदा extern "C" ब्लॉकों को दूर करने की जरूरत नहीं है तो।

मुझे नहीं पता कि समस्या केवल अनुकूलित बिल्डों के लिए क्यों होगी, सिवाय इसके कि .c या .cpp फ़ाइल जिसमें कॉलिंग फ़ंक्शन के गैर-इनलाइन संस्करण शामिल हैं, शीर्षलेख सही हो जाते हैं, और वहां केवल आवश्यकता होती है एक अनुवाद इकाई बनें जो हेडर गलत हो जाती है और समस्या को देखने के लिए कॉलिंग फ़ंक्शन को रेखांकित करती है।

+0

धन्यवाद! यह एक अच्छा विचार हो सकता है कि समस्या का पता लगाने के लिए, यदि यही कारण है। अफसोस की बात है, मेरे पास अगले सप्ताह शुक्रवार को देखने का समय होगा, फिर वापस रिपोर्ट करेंगे। – Thilo

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