2012-02-15 11 views
6

मैं फ्लैवियन कोलोहो, linked here के काम को दोहराने की कोशिश कर रहा हूं। उन्होंने सिथॉन और जीएनयू वैज्ञानिक पुस्तकालय (जीएसएल) का इस्तेमाल किया ताकि वे यादृच्छिक संख्या उत्पन्न करने में पाइथन पर भारी गति प्राप्त कर सकें। जब मैं अजगर में मेरी संकलित Cython कोड आयात (आदेश import cgibbs के साथ), मैं निम्नलिखित त्रुटि मिलती है:बाहरी सी लाइब्रेरी को जोड़ने पर साइथन से आयात त्रुटि

ImportError: dlopen(./cgibbs.so, 2): Symbol not found: _gsl_rng_mt19937 
    Referenced from: /Users/wesley/scratch/cython/cgibbs.so 
    Expected in: dynamic lookup 

आप देखेंगे शिकायत यह है कि प्रतीक _gsl_rng_mt19937 नहीं पाया जा सकता है है। जिस फ़ंक्शन को मैं लिंक करने का प्रयास कर रहा हूं उसे gsl_rng_mt19937 (कोई अग्रणी अंडरस्कोर नहीं कहा जाता है), और इसी तरह यह मेरी .pyx फ़ाइल में दिखाई देता है। मुझे लगता है कि साइथन किसी भी तरह से अग्रणी अंडरस्कोर जोड़कर समस्या पैदा कर रहा है।

समस्या निवारण को आसान बनाने के लिए, मैंने कोड को तोड़ दिया है और इसे नीचे पोस्ट किया है। मेरा सिस्टम है: मैक ओएसएक्स 10.7 (शेर) पाइथन 2.7.2 (32-बिट), जीसीसी-4.0 (जिसे मैं 32-बिट फॉर्म में जीएसएल पुस्तकालयों को संकलित करने के लिए उपयोग करता था), जीएसएल 1.15, और साइथन v0.15.1 चला रहा था।

यहाँ cgibbs.pyx की सामग्री है:

#declaring external GSL functions to be used 
cdef extern from "math.h": 
    double sqrt(double) 

cdef double Sqrt(double n): 
    return sqrt(n) 

cdef extern from "gsl/gsl_rng.h": 
    ctypedef struct gsl_rng_type: 
     pass 
    ctypedef struct gsl_rng: 
     pass 
    gsl_rng_type *gsl_rng_mt19937 
    gsl_rng *gsl_rng_alloc(gsl_rng_type * T) 

cdef extern from "gsl/gsl_randist.h": 
    double gamma "gsl_ran_gamma"(gsl_rng * r,double,double) 
    double gaussian "gsl_ran_gaussian"(gsl_rng * r,double) 


cdef gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937) 

त्रुटि दूर चला जाता है अगर मैं अपने cgibbs.pyx की अंतिम पंक्ति बाहर टिप्पणी है, लेकिन फिर मैं वास्तव में बाहरी पुस्तकालय का उपयोग नहीं कर सकते हैं ... कोई भी अंतर्दृष्टि जो आप पेशकश कर सकते हैं सराहना की है। धन्यवाद!

उत्तर

4

@ChuiTey के लिए धन्यवाद, मैंने पाया कि otool और nm मैक पर उपकरण हैं जो लिनक्स पर objdump करता है जो कर सकते हैं। nm के साथ मैंने पाया कि अग्रणी अंडरस्कोर libgsl.a लाइब्रेरी में प्रतीक नाम का हिस्सा हैं।

एक बार मुझे पता चला कि लिंकर (मेरे मामले में, ld) सही नाम की तलाश में था, यह स्पष्ट था कि यह सही जगह पर नहीं देख रहा था। और इस तरह मैंने सीखा कि हेडर फाइलें उन लाइब्रेरीज़ के स्थान को नहीं जानती हैं, जिन्हें वे लिंक करते हैं (डुह!) मुझे लिंकर चलाने वाले कमांड में -lgsl विकल्प जोड़ने की आवश्यकता है (इसके लिए libgsl.a निर्देशिका में है जहां अपने लिंकर पुस्तकालयों के लिए लग रहा है - मेरी मशीन पर, कि /usr/local/lib है)

मैं भी /usr/local/lib से libgsl.dylib स्थानांतरित करने के लिए है, क्योंकि यह एक 64-बिट प्लेटफॉर्म के लिए संकलित किया गया था और मैं 32-बिट अजगर का उपयोग कर रहा था।।

-lgsl लिंकर विकल्प निर्दिष्ट करने का एक आसान तरीका होना चाहिए जब विकृति या मेकफ़ाइल के साथ साइथन कोड संकलित करना; अभी के लिए मैं संकलन के लिए दो बार जीसीसी-4.0 चला रहा हूं और फिर मॉड्यूल को लिंक करता हूं। बैश कमांड लाइन से एक Cython मॉड्यूल संकलित करने के लिए मेरे कार्यप्रवाह है:

cython cgibbs.pyx 
gcc-4.0 -m32 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c cgibbs.c -o cgibbs.o 
gcc-4.0 -bundle -undefined dynamic_lookup -lgsl -arch i386 -g cgibbs.o -o cgibbs.so 

कौन सा cgibbs.so, एक Cython मॉड्यूल है कि अजगर 2.7 में आयात किया जा सकता पैदा करता है।

2

निर्यात किए गए कार्यों के लिए अंडरस्कोर तैयार करना name mangling के रूप में जाना जाता है। विंडोज़ पर, सीडीईसीएल सम्मेलन एक अंडरस्कोर जोड़ता है (अन्य सम्मेलनों में अधिक जटिल योजनाएं होती हैं)।

यह हो सकता है कि आपने अपनी जीएसएल लाइब्रेरी बनाने के दौरान कॉलिंग सम्मेलन को सही तरीके से निर्दिष्ट नहीं किया हो। आपको objdump का उपयोग करके किन नामों का निर्यात किया जा रहा है, इस पर एक नजर डालने में सक्षम होना चाहिए।

क्या जीएसएल पहले से ही SWIG wrappers प्रदान नहीं करता है?

+0

मैं बड़ा घूँट से पता नहीं है - शायद मैं करने के लिए है, हालांकि चाहिए। – Wesley

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