2011-09-13 8 views
7

मैं कुछ जीएनयू उपकरण, यानी जीएनयू सी ++ कंपाइलर (जी ++) और जीएनयू लिंकर (एलडी) का उपयोग कर एक साझा लाइब्रेरी (.so) फ़ाइल बनाने के लिए उपयोग कर रहा हूं एक बाइनरी निष्पादन योग्य फ़ाइल।जीएनयू लिंकर (एलडी) को एक प्रतीक निर्यात करने के लिए समस्या

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

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

जहां फ़ाइल ${top_srcdir}/dynamic_symbol_table.txt में निम्न सामग्री शामिल है;

{ 
    extern "C++" 
    { 
    "ToolboxManager::registerToolbox*"; 
    }; 
}; 

नोट फ़ाइल में तारांकित (*) के उपयोग के सभी प्रतीकों कि ToolboxManager::registerToolbox के साथ शुरू निर्यात करने के लिए लिंकर मजबूर करने के लिए।

जब मैं परिणामी बाइनरी निष्पादन योग्य पर जीएनयू एनएम उपयोगिता (nm -C -g ./a.out) चलाता हूं, तो यह उपर्युक्त वर्ग विधि के बारे में निम्न जानकारी प्रदर्शित करता है;

08053da0 T ToolboxManager::registerToolbox 
      ( 
      std::string&, 
      std::string&, 
      std::map 
      < 
      std::string, 
      Factory_DSPB_Base*, 
      std::less 
      < 
       std::string 
      >, 
      std::allocator 
      < 
       std::pair 
       < 
       std::string const, 
       Factory_DSPB_Base* 
       > 
      > 
      >& 
      ) 

या, एनएम उपयोगिता के रूप में ऊपर लागू किया गया है, लेकिन -सी कमांड लाइन स्विच के उपयोग के बिना इस समय;

08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

अभी तक, यह ठीक दिखता है। कक्षा विधि ToolboxManager::registerToolbox की परिभाषा के सामने "टी", यह दर्शाता है कि विधि फ़ाइल के टेक्स्ट/कोड अनुभाग में रहती है।

इसी प्रकार, यदि मैं साझा लाइब्रेरी फ़ाइल पर एनएम उपयोगिता (nm -C -g ./toolbox.so) चलाता हूं, तो यह उसी उपर्युक्त वर्ग विधि के बारे में निम्न जानकारी प्रदर्शित करता है;

U ToolboxManager::registerToolbox 
    (
    std::string&, 
    std::string&, 
    std::map 
    < 
    std::string, 
    Factory_DSPB_Base*, 
    std::less 
    < 
    std::string 
    >, 
    std::allocator 
    < 
    std::pair 
    < 
     std::string const, 
     Factory_DSPB_Base* 
    > 
    > 
    >& 
) 

यह भी ठीक दिखता है। कक्षा विधि ToolboxManager::registerToolbox की परिभाषा के सामने "यू", इंगित करता है कि साझा लाइब्रेरी फ़ाइल में विधि अपरिभाषित है।

हालांकि, एक समस्या तब होती है जब मैं कमांड लाइन से बाइनरी एक्टेक्टेबल चलाता हूं और इस समस्या के परिणामस्वरूप निम्न त्रुटि संदेश प्रदर्शित होता है;

./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

इस रनटाइम संदेश में दिखाई देने वाली उलझन वाली क्लास विधि नाम नीचे दी गई है, जैसा कि दो पंक्तियों में से पहला है। तुलनात्मक उद्देश्यों के लिए, उपरोक्त से गुस्सा वर्ग विधि का नाम (और जिसे nm -g कमांड का उपयोग करके उत्पन्न किया गया था) को दो पंक्तियों के दूसरे के रूप में नीचे दिखाया गया है;

_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

जैसा देखा जा सकता है, दो उलझन वाले नाम समान हैं। इसलिए, मैं समझ नहीं पा रहा हूं कि अपरिभाषित प्रतीक रनटाइम पर क्यों हल नहीं किया जा सकता है।

फिर मैंने बाइनरी निष्पादन योग्य को फिर से जोड़ा, हालांकि इस बार मैंने निम्नलिखित लिंकर कमांड को प्रतिस्थापित किया;

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

इस के साथ;

-Wl,--export-dynamic 

--export-dynamic लिंकर विकल्प जीएनयू लिंकर गतिशील प्रतीक मेज पर सभी प्रतीकों को जोड़ने के लिए निर्देश देता है।

यदि फिर बाइनरी निष्पादन योग्य फिर से चलाया गया। इस बार यह सही ढंग से निष्पादित किया गया था और dlopen फ़ंक्शन पर कॉल के परिणामस्वरूप एक अपरिभाषित प्रतीक त्रुटि नहीं हुई थी। यह मुझे पूरी तरह से परेशान करता है, क्योंकि ऐसा लगता है कि प्रतीक को बाइनरी निष्पादन योग्य के प्रारंभिक संस्करण में सही ढंग से निर्यात किया जा रहा है। क्या कोई यहां समस्या को देखने में सक्षम है? किसी भी सहायता की सराहना की जाएगी।

अग्रिम धन्यवाद।

उत्तर

3

मैंने इस समस्या को हल करने में कामयाब रहे हैं। मैंने पाया है कि अगर मैं निम्नलिखित पंक्ति से उद्धरण चिह्न हटा देता हूं;

"ToolboxManager::registerToolbox*" 
फ़ाइल ${top_srcdir}/dynamic_symbol_table.txt और उसके बाद फिर से लिंक बाइनरी निष्पादन के भीतर

, तो यह काम करता है। यही है, dlopen समारोह अब और असफल नहीं होगा।

मैं इस बात पर आश्चर्य नहीं कर सकता कि यह इस वेब साइट पर जीएनयू binutils मेलिंग सूची पर इस सवाल पूछने के लिए अधिक उचित होगा।

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