2010-03-01 7 views
37

मेरे पास एक साझा लाइब्रेरी है जो किसी अन्य (तृतीय-पक्ष) साझा लाइब्रेरी से जुड़ी है। मेरी साझा लाइब्रेरी को तब मेरे आवेदन में डलोपेन का उपयोग करके लोड किया जाता है। यह सब ठीक काम करता है (माना जाता है कि फ़ाइलें उचित पथ आदि में हैं)।साझा जीबीसी साझा पुस्तकालयों में अपरिभाषित संदर्भों के बारे में सूचित करने के लिए

अब समस्या यह है कि जब मैं अपनी लाइब्रेरी को लिंक करता हूं तो मुझे तृतीय-पक्ष साझा लाइब्रेरी के लिंक करने के लिए निर्दिष्ट करने की आवश्यकता भी नहीं होती है। जीसीसी इसे अपरिभाषित संदर्भों के बारे में रिपोर्टिंग त्रुटियों के बिना स्वीकार करते हैं। तो, सवाल; मैं जीसीसी को अपरिभाषित संदर्भों के बारे में सूचित करने के लिए कैसे मजबूर कर सकता हूं?

यदि मैं अपनी लाइब्रेरी को निष्पादन योग्य (अस्थायी रूप से) बदलने के लिए बदलता हूं, तो मुझे अनिर्धारित संदर्भ मिलते हैं (जब लिंकर को लाइब्रेरी की आपूर्ति नहीं होती है)। (ठीक काम करता है अगर मैं इसे निर्दिष्ट करें।)

अर्थात, और निम्नलिखित किया जाता है:

g++ -fPIC -shared -o libb.so b.o 
g++ -fPIC -shared -o liba.so a.o 
g++ -o a.exe a.cpp 

कहाँ दूसरी पंक्ति में कोई त्रुटि नहीं देता और तीसरी पंक्ति एक अपरिभाषित संदर्भ के बारे में शिकायत।

नमूना कोड:

a.h:

class a 
{ 
public: 
    void foobar(); 
}; 

a.cpp:

#include "a.h" 
#include "b.h" 

void a::foobar() 
{ 
    b myB; 
    myB.foobar(); 
} 

int main() 
{ 
    a myA; myA.foobar(); 
} 

b.h:

b.cpp:

#include "b.h" 

void b::foobar() 
{ 
} 

उत्तर

33

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

जी ++ कमरा साझा -Wl, -soname, libmylib.so.5 -Wl, - कोई अपरिभाषित -ओ libmylib.so.1.1 mylib.o -lthirdpartylib

+0

नहीं, बिल्कुल कोई त्रुटि नहीं। –

+0

क्या आप लिंकर आउटपुट प्रदान कर सकते हैं? –

+0

एचएम, मैंने शपथ ली थी कि मैंने पहले ऐसा किया था और आउटपुट के रूप में कुछ भी नहीं मिला। ऐसा करने के लिए फिर से यह काम ठीक लग रहा था (यानी मुझे एक त्रुटि मिलती है!) –

1

आप एलडी (जो जीसीसी चल रहा है) नहीं बना सकते हैं, जो उस लाइब्रेरी पर ध्यान देते हैं जो लिंक में नहीं है। आप आक्रामक रिपोर्टिंग प्राप्त करने के लिए RTLD_LAZY को बंद कर सकते हैं, और आप एक यूनिट टेस्ट जोड़ सकते हैं जो कि इन समस्याओं को दूर करने के लिए लिंक के ठीक बाद चलता है।

+0

आप क्या कर सकते हैं, और प्रश्नकर्ता क्या कर रहा था, आपको यह बताने के लिए 'एलडी' मिल गया है "मुझे नहीं पता कि आप कहां सोचते हैं कि ये प्रतीक आ रहे हैं, लेकिन वे किसी भी में नहीं हैं पुस्तकालयों ने आपने मुझे बताया है। " –

13

अधिक अनुसंधान के बाद, मुझे एहसास हुआ कि सामान किस तरह काम करता है। साझा पुस्तकालयों के अपरिभाषित प्रतीकों में हेरफेर करने के लिए दो लिंकर विकल्प हैं:

पहला वाला --no-undefined है। यह अनसुलझे प्रतीकों की रिपोर्ट करता है जिन्हें चरणबद्ध करने पर तत्काल हल नहीं किया जाता है। जब तक कि लिंक साझा की गई साझा लाइब्रेरी में नहीं मिलता है, या तो मैन्युअल रूप से (-l स्विच के साथ) या स्वचालित रूप से (libgcc_s, सी ++ रनटाइम; libc, सी रनटाइम; ld-linux-**.so, डायनामिक लिंकर यूटिल) उठाया गया है, --no-undefined इसे त्रुटि के रूप में रिपोर्ट करता है। प्रश्नकर्ता की यही कुंजी है।

एक और कुंजी है, --no-allow-shlib-undefined (जिसका वर्णन --no-undefined भी सुझाता है)। यह जांचता है कि साझा पुस्तकालयों में परिभाषा जो आप अपनी साझा लाइब्रेरी को से लिंक करते हैं, संतुष्ट हैं। इस विषय में दिखाए गए मामले में यह कुंजी थोड़ा उपयोग नहीं है, लेकिन यह उपयोगी हो सकती है।हालांकि, इसकी अपनी बाधाएं हैं।

--allow-shlib-undefined 
    --no-allow-shlib-undefined 
     Allows (the default) or disallows undefined symbols in shared 
     libraries (It is meant, in shared libraries _linked_against_, not the 
     one we're creating!--Pavel Shved). This switch is similar to --no-un- 
     defined except that it determines the behaviour when the undefined 
     symbols are in a shared library rather than a regular object file. It 
     does not affect how undefined symbols in regular object files are 
     handled. 

     The reason that --allow-shlib-undefined is the default is that the 
     shared library being specified at link time may not be the same as 
     the one that is available at load time, so the symbols might actually 
     be resolvable at load time. Plus there are some systems, (eg BeOS) 
     where undefined symbols in shared libraries is normal. (The kernel 
     patches them at load time to select which function is most appropri- 
     ate for the current architecture. This is used for example to dynam- 
     ically select an appropriate memset function). Apparently it is also 
     normal for HPPA shared libraries to have undefined symbols. 

बात यह है कि क्या इसके बाद के संस्करण कहा जाता है भी सच है, उदाहरण के लिए, लिनक्स सिस्टम के लिए है, जहां के आंतरिक दिनचर्या में से कुछ साझा है:

मैनपेज के बारे में क्यों यह डिफ़ॉल्ट नहीं कर रहा है कुछ औचित्य प्रदान करता है पुस्तकालय ld-linux.so में कार्यान्वित किया गया है, गतिशील लोडर (यह निष्पादन योग्य और साझा लाइब्रेरी दोनों है)। जब तक आप किसी भी तरह से लिंक है, तो आप कुछ इस तरह मिल जाएगा:

/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `[email protected]_2.3' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 
/lib64/libc.so.6: undefined reference to `[email protected]_PRIVATE' 

ये लोडर, ld-linux.so से अपरिभाषित संदर्भ हैं। यह मंच-विशिष्ट है (उदाहरण के लिए, मेरे सिस्टम पर सही लोडर /lib64/ld-linux-x86-64.so है)। the Mandriva wiki पर

g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined /lib64/ld-linux-x86-64.so.2 
+0

नहीं, अगर मैं --no-allow-shlib-undefined या --no-undefined का उपयोग करता हूं, तो कोई भी त्रुटि नहीं है। –

+0

@ फ़्रेड्रिक, मुझे लगता है, आप '-Wl,' सामान जोड़ना भूल गए हैं। यह * त्रुटि दिखाता है, हालांकि * वह नहीं * जिसे आप चाहते थे। लेकिन यह आपके पास सबसे ज्यादा हो सकता है। –

+0

ऐसा लगता है - अपेक्षित के रूप में अनिर्धारित काम नहीं करता है - - कोई-अनुमति-श्लिब-अपरिभाषित नहीं है। (जैसा कि आप कहते हैं काम करते हैं।) –

2

भी इस का एक अच्छा विचार-विमर्श नहीं है: आप अपने पुस्तकालय के साथ लोडर लिंक कर सकते हैं और यहां तक ​​कि जाँच ऊपर दिखाए मुश्किल संदर्भ।