2011-03-17 12 views
17

मैं बूस्ट.पथन का उपयोग करके पाइथन में अपने सी ++ क्लासेस का पर्दाफाश करने की कोशिश कर रहा हूं। यहां मैं जो करने का प्रयास कर रहा हूं उसका एक सरल संस्करण यहां दिया गया है:Boost.Python संदर्भ द्वारा कॉल करें: TypeError: C++ प्रकार के लिए कोई to_python (by-value) कनवर्टर नहीं मिला:

मेरे पास एक श्रेणी ए है जो बूस्ट :: नॉनकोपीबल और द्वितीय श्रेणी बी से प्राप्त करने वाला एक तरीका है जो ए को तर्क के रूप में संदर्भित करता है।

class A : boost::noncopyable { /*...*/ }; 

class B { 

public: 

    virtual void do_something(A& a) { 
     /*...*/ 
    } 
}; 

मैं वर्गों को उजागर कर रहा हूँ इस प्रकार है:

/* Wrapper for B, so B can be extended in python */ 
struct BWrap : public B, wrapper<B> { 

    void do_something(A &a) { 

     if (override do_something = this->get_override("do_something")) { 
      do_something(a); 
      return; 
     } 
     else { 
      B::do_something(a); 
     } 
    } 

    void default_do_something(A& a) { this->B::do_something(a); } 
}; 

BOOST_PYTHON_MODULE(SomeModule) { 

    class_<A, boost::noncopyable>("A"); 

    class_<BWrap, boost::noncopyable>("B") 
     .def("do_something", &B::do_something, &BWrap::default_do_something) 
    ; 
} 

मैं इस तरह अजगर में बी का विस्तार:

test.py:

import SomeModule 


class BDerived(SomeModule.B): 

    def do_something(self, a): 
     pass 

और फोन बढ़ाया बी इस तरह:

try { 
    py::object main = py::import("__main__"); \ 
    py::object global(main.attr("__dict__")); \ 
    py::object result = py::exec_file("test.py", global, global); \ 
    py::object pluginClass = global["BDerived"]; \ 
    py::object plugin_base = pluginClass(); \ 

    B& plugin = py::extract<B&>(plugin_base) BOOST_EXTRACT_WORKAROUND; 

    A a; 
    B.do_something(a); 
} 
catch (py::error_already_set) { 
    PyErr_Print(); 
} 

हालांकि इस एक त्रुटि संदेश में परिणाम: boost::noncopyable से प्राप्त नहीं है कोड किसी भी त्रुटि के बिना चलता है, लेकिन do_something(A& a) में तर्क एक समारोह कॉल भले ही यह में पारित कर दिया है के दौरान उन्हें कॉपी हो जाता है

TypeError: No to_python (by-value) converter found for C++ type: A 

तो A संदर्भ से। लेकिन A पर गैर-लोकप्रिय आवश्यकता को हटाने का एक विकल्प नहीं है क्योंकि यह किसी कारण से है।

समस्या का समाधान कैसे करें कोई सुझाव?

धन्यवाद।

+1

यहां लैंडिंग लोगों के लिए: बूस्ट 1.60.0 में हाल ही में एक बग है जो इस तरह दिखता है, बूस्ट 1.61.0 में तय किया जाना चाहिए, https://github.com/boostorg/python/pull/59 भी देखें –

+1

@ केनेथहोस्ट आपको बहुत धन्यवाद !!! यदि आप चारों ओर घूमने के हफ्तों नहीं हैं तो आपने मुझे कई दिनों से बचाया !! बहुत खुश मुझे यह छोटी टिप्पणी मिली !! :) – Mangostaniko

उत्तर

15

B.do_something(a); से B.do_something(boost::ref(a)); बदलें।

बूस्ट मैनुअल में Calling Python Functions and Methods देखें।

+0

बहुत बहुत धन्यवाद! आपने मुझे सही संकेत दिया। भले ही मुझे इसे रैपर क्लास BWrap 'do_something (boost :: ref (a)) में बदलना पड़ा; 'और' bdo_something (a); 'को कॉल करते समय नहीं। अविश्वसनीय है कि गुगलिंग के घंटों ने मुझे कभी भी संकेत नहीं दिया। एक बार फिर धन्यवाद! – Kai

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