6

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

class listener{ 
     public: 
      listener(){} 
      void alert(cham::event::event e){ 
       if (responses[e.getName()]) 
        responses[e.getName()](e.getData()); 
      } 
      void setResponse(std::string n, boost::function<void (std::string d)> c){responses.insert(make_pair(n, c));} 
      void setManager(_manager<listener> *m){manager = m;} 
     private: 
      std::map<std::string, boost::function<void (std::string d)> > responses; 
      _manager<listener> *manager; 

आप देख सकते हैं, समारोह setResponse समस्या है। इसके लिए एक समारोह को पारित करने की आवश्यकता है, और, दुर्भाग्यवश, बूस्ट :: पायथन इस स्थिति में इसके कनवर्टर जादू को लागू नहीं करता है। जब निम्नलिखित की तरह कहा जाता है:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
Boost.Python.ArgumentError: Python argument types in 
    listener.setResponse(listener, str, function) 
did not match C++ signature: 
    setResponse(cham::event::listener {lvalue}, std::string, boost::function<void()(std::string)>) 

तो, मेरे सवाल है, मैं कैसे इसे ठीक कर सकते हैं:

>>> import chameleon 
>>> man = chameleon.manager() 
>>> lis = chameleon.listener() 
>>> def oup(s): 
... print s 
... 
>>> lis.setResponse("event", oup) 

यह इस त्रुटि देता है? इसे या तो ओवरलोडिंग या रैपर का उपयोग करना होगा, क्योंकि मैं पुस्तकालय को सी ++ द्वारा कॉल करने योग्य रखना चाहता हूं।

+0

+1 क्योंकि मुझे लगता है कि बूस्ट :: पायथन एक बहुत अच्छा विचार है। – zmbq

उत्तर

2

आप एक आवरण के आसपास setResponse है, जो एक समारोह के बजाय एक boost::python::object लेता है की आवश्यकता होगी। इसे किसी ज्ञात स्थान पर bp::object स्टोर करना चाहिए (शायद listener सबक्लास का सदस्य चर)।

फिर बेस setResponse पर एक अलग सी ++ फ़ंक्शन पास करें, जो कि bp::object में फ़ंक्शन को लुकअप और कॉल करने के बारे में जानेंगे। यदि घटनाओं को एक अलग धागे पर बुलाया जाता है, तो आपको यहां पर चर्चा की गई पाइथन के ग्लोबल इंटरप्रेटर लॉक के उचित संचालन को सुनिश्चित करने की आवश्यकता होगी: boost.python not supporting parallelism?

+1

धन्यवाद! मैंने इसे पढ़ने से पहले इसे ठीक किया, एक ही पद्धति का उपयोग करके। मैंने अभी श्रोता के लिए एक अतिरिक्त टेम्पलेट तर्क जोड़ा है, जो कि :: :: बूस्ट :: फ़ंक्शन के बजाय पायथन :: ऑब्जेक्ट में पारित किया गया है, और इसे टाइप किए गए python_listener के साथ टाइप किया गया है। एक जादू की तरह काम करता है। – chameco

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