2012-07-30 17 views
6

के साथ अनिर्धारित प्रतीक "टाइपइन्फो" मैं लिनक्स पर जीसीसी 4.6 का उपयोग करके साझा लाइब्रेरी बनाने की कोशिश कर रहा हूं, जो गतिशील रूप से लोड हो रहा है। जैसा कि वेब पर कई लेखों के साथ-साथ पिछले प्रश्नों में वर्णित है, मैं पुस्तकालय में ऑब्जेक्ट्स बनाने और नष्ट करने के लिए सी-स्टाइल फैक्ट्री विधियों को प्रदान करता हूं। कोड - कम से कम रूप में - इस तरह दिखता है:गतिशील रूप से लोड की गई लाइब्रेरी

base.h:

class base { 
public: 
    base(); 
    virtual ~base(); 
    virtual int value() = 0; 
}; 

base.cpp:

#include "base.h" 
base::base() {} 
base::~base() {} 

main.cpp:

#include "base.h" 
#include <dlfcn.h> 
#include <iostream> 

int main() { 
    void* handle = dlopen("liblib.so", RTLD_NOW); 
    if(handle == NULL) std::cout << dlerror() << std::endl; 

    // dlsym, ... 
} 

lib। सीपीपी:

class derived : public base { 
public: 
    derived() {} 
    virtual ~derived() {} 
    virtual int value() { return 42; } 
}; 

extern "C" derived* create_object() { 
    return new derived(); 
} 

यह साथ ठीक संकलित:

g++ -shared -fPIC lib.cpp -o liblib.so 
g++ base.cpp main.cpp -ldl -o app 

रनटाइम पर, लेकिन यह क्योंकि एक typeinfo प्रतीक

liblib.so: undefined symbol: _ZTI4base 

पिछले प्रश्न मैं यहां पाया में लापता की दुर्घटनाओं, यह त्रुटि आमतौर पर की वजह से या तो कुछ याद आ रही थी "= 0;" या वर्चुअल फ़ंक्शन की अनुपलब्ध परिभाषा। हालांकि ऊपर दिए गए उदाहरण में, बेस :: मान शुद्ध आभासी है और विनाशक की परिभाषा है। अजीब पर्याप्त एनएम रिपोर्ट _ZTI4base के रूप में अनुप्रयोग में definied:

$ nm app | grep _ZTI4base 
0000000000601050 V _ZTI4base 

तो क्यों इस परिभाषा का उपयोग लिंकर नहीं है?

कोड कोड प्राप्त करने के लिए अब तक एकमात्र तरीका हैडर हेडर फ़ाइल में निर्माता और विनाशक को कार्यान्वित करना है। ऐसा करने के बाद, आधार के लिए संबंधित प्रतीक liblib.so में एनएम द्वारा रिपोर्ट किए जाते हैं और पूरी तरह से ऐप से गायब हो जाते हैं, जिसका शायद मतलब है कि उनकी परिभाषाएं लाइब्रेरी में संकलित की गई थीं, ऐप में नहीं, जो कि मैं हासिल नहीं करना चाहता था। क्या किसी को यह पता है कि उपर्युक्त काम करने के बिना इसे कैसे प्राप्त किया जाए?

+1

फ़ंक्शन के असंगत नाम को देखने के लिए '--demangle'' nm' दें। – Shahbaz

उत्तर

2

प्रोग्राम को जोड़ने के दौरान आपको -rdynamic विकल्प की आवश्यकता है, इसके प्रतीकों को निर्यात करने और उन्हें dlopen() से लोड की गई पुस्तकालयों में उपलब्ध कराएं।

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