मेरे पास एक लाइब्रेरी है जो ऑब्जेक्ट्स (कक्षा ए के उदाहरण) बनाती है और उन्हें एक पायथन प्रोग्राम में पास करती है जो उनके तरीकों को कॉल करने में सक्षम होना चाहिए।सी ++ कक्षाओं के उदाहरणों को बढ़ावा देने के साथ पाइथन को पास करना :: पायथन
असल में मेरे पास सी ++ वर्ग के उदाहरण हैं और मैं उन्हें अजगर से उपयोग करना चाहता हूं। कभी-कभी उस वस्तु को कुछ जोड़ों के लिए सी ++ में वापस भेज दिया जाना चाहिए।
#include <boost/python.hpp>
#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace boost::python;
int calls = 0;
struct A
{
int f() { return calls++; }
~A() { std::cout << "destroyed\n"; }
};
shared_ptr<A> existing_instance;
void New() { existing_instance = shared_ptr<A>(new A()); }
int Count(shared_ptr<A> a) { return a.use_count(); }
BOOST_PYTHON_MODULE(libp)
{
class_<A>("A")
.def("f", &A::f)
;
def("Count", &Count);
register_ptr_to_python< shared_ptr<A> >();
}
कोड हिस्सा है जहां अजगर existing_instance
हो जाता है का अभाव:
मैं निम्नलिखित आवरण फ़ाइल (मान लेते हैं कि New
समारोह सी ++ कोड में कहीं भी कहा जाता है भी नहीं) बनाया। मैंने इसे पेस्ट नहीं किया, लेकिन आइए बस यह कहें कि मैं उस उद्देश्य के लिए कॉलबैक तंत्र का उपयोग करता हूं।
इस कोड काम करता है लेकिन मैं कुछ प्रश्न हैं:
गणना समारोह में (और अन्य सभी सी ++ हेरफेर कार्यों में) यह
a
ऐसे ही पारित करने के लिए ठीक है या यहconst shared_ptr<A>&
की तरह कुछ करने के लिए बेहतर है ? पाइथन बूस्ट प्रलेखन में मिले कोड स्निपेट में संदर्भ अक्सर उपयोग किया जाता है लेकिन मुझे अंतर नहीं समझता है (बेशक उच्च संदर्भ काउंटर होने के अलावा)।क्या यह कोड "सुरक्षित" है? जब मैं मौजूदा_इंस्टेंस को पायथन पर पास करता हूं, तो उसका काउंटर बढ़ जाएगा (केवल एक बार, अगर पाइथन में भी मैं ऑब्जेक्ट की अधिक प्रतियां बना देता हूं) तो कोई तरीका नहीं है कि सी ++ कोड वस्तु को नष्ट कर सकता है जहां तक पाइथन धारण करता है कम से कम एक "प्रतिलिपि"। क्या मैं सही हूँ? मैंने पॉइंटर्स के साथ खेलने की कोशिश की और ऐसा लगता है कि मैं सही हूं, मैं बस सुनिश्चित करने के लिए कह रहा हूं।
मैं अजगर के उदाहरण बनाने से पाइथन को रोकना चाहता हूं। उन्हें केवल सी ++ कोड से ही पारित किया जाना चाहिए। मैं इसे कैसे प्राप्त कर सकता हूं? संपादित:
class_<A, boost::noncopyable>("A", no_init)
के बीच का अंतर (व्यवहार में) क्या है "class_ <एक, को बढ़ावा देने :: noncopyable> ('ए', no_init)" और "बढ़ावा: : पायथन :: class_ <ए, बूस्ट :: shared_ptr > ("ए", बूस्ट :: पायथन :: no_init) "? मेरे द्वारा पोस्ट किया गया कोड "class_" के बाद "boost :: shared_ptr " निर्दिष्ट किए बिना पूरी तरह से काम करता है। तो मुझे इसकी आवश्यकता क्यों होगी? – Emiliano
यह डिफ़ॉल्ट प्रकार निर्दिष्ट करता है जो वास्तव में एक पायथन 'ए' द्वारा लपेटा जाएगा - इसलिए यदि आपके पास एक सी ++ फ़ंक्शन है जो 'ए', 'ए *' साझा_ptr या कुछ भी समान देता है, और इसे पायथन पर बेनकाब करता है, तो वापसी मूल्य को shared_ptr के रूप में आयोजित किया जाएगा - यदि आप चाहते हैं कि आप अक्सर इन वस्तुओं को पाइथन में और बाहर से गुजर रहे हैं, क्योंकि सभी स्वामित्व सही ढंग से संभाले जाएंगे। अधिक जानकारी के लिए http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/class.html#HeldType (esp। Point 2) देखें। –
James