2012-08-31 15 views
9

पर एक boost shared_ptr को पास करना संभव है, मेरे पास एक ऑब्जेक्ट है जो C++ में shared_ptr में आयोजित होता है। ऑब्जेक्ट को पाइथन के भीतर से अजगर बाइंडिंग के माध्यम से एक्सेस किया जाता है और इसे एक और बाध्य सी ++ फ़ंक्शन में भेज दिया जाता है जो इसे पकड़ने की कोशिश करता है। ऐसा प्रतीत होता है कि जब ऑब्जेक्ट सी ++ से पायथन तक जाता है तो इसे एक साझा_प्टर से एक पायथन ऑब्जेक्ट में परिवर्तित किया जाता है। फिर जब यह सी ++ में वापस जाता है तो इसे पायथन ऑब्जेक्ट से एक नए shared_ptr में परिवर्तित किया जाता है, हालांकि यह shared_ptr प्रारंभिक होल्डिंग shared_ptr से असंबंधित नहीं है।क्या सी ++ से पायथन तक साझा किया गया है और सी ++

क्या बूस्ट-पायथन बाइंडिंग सेट करना संभव है ताकि पायथन ऑब्जेक्ट से share_ptr में रूपांतरण मूल shared_ptr internals का संदर्भ हो?

नीचे दिया गया संक्षिप्त कोड है जिसे मैंने समस्या दिखाने के लिए उपयोग किया है।

इस उदाहरण में एक वस्तु प्रारंभ में साझा_प्टर नामक s_inital में आयोजित की जाती है। इसे getSharedPtr फ़ंक्शन के माध्यम से अजगर के भीतर से पकड़ लिया जाता है, फिर putSharedPtr फ़ंक्शन के माध्यम से वापस C++ में धक्का दिया जाता है। PutSharedPtr के अंदर इसे weak_ptr s_copied में कॉपी किया गया है। डीबगर में पॉइंटर्स का निरीक्षण करने से पता चलता है कि putSharedPtr में इस्तेमाल किए गए shared_ptr में समान संदर्भ नहीं है जो आंतरिक रूप से s_initial के रूप में गिनती करता है। अंतिम जोर आग लग जाएगा क्योंकि कमजोर पॉइंटर s_copied केवल एक मजबूत सूचक (PutSharedPtr में इस्तेमाल सूचक) से संबंधित था और PutSharedPtr समाप्त हो जाने के बाद सूचक को नष्ट कर दिया गया था।

static shared_ptr<Captured> s_initial; 
static weak_ptr<Captured> s_copied; 

class UseSharedPtr 
{ 
public: 
    shared_ptr<Captured> getSharedPtr() 
    { 
     return s_initial; 
    } 

    void putSharedPtr(shared_ptr<Captured> ptr) 
    { 
     s_copied = ptr; 
    } 
}; 


BOOST_PYTHON_MODULE(test) 
{ 
    class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init); 
    class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>()) 
     .def("getSharedPtr", &UseSharedPtr::getSharedPtr) 
     .def("putSharedPtr", &UseSharedPtr::putSharedPtr) 
    ; 
} 



    s_initial = make_shared<Captured>(); 

    const char* chunk = "\ 
from test import UseSharedPtr \n\ 
x = UseSharedPtr() \n\ 
ptr = x.getSharedPtr() \n\ 
x.putSharedPtr(ptr)\n\ 
del x \n\ 
del ptr \n\ 
"; 
    object result = exec(chunk, mainNamespace, mainNamespace); 

    assert(s_copied.lock()); 
+0

पूरे 'UseSharedPtr' वर्ग के उद्देश्य क्या है? जैसे ही 'कैप्चर' का खुलासा हुआ है, बूस्ट :: पायथन सही तरीके से संभाल लेंगे। – eudoxos

+0

मुझे लगता है कि यह सिर्फ एक उदाहरण के रूप में था। जबकि boost.python साझा वर्ग के तरीकों को सही ढंग से कॉल करेगा, इसमें अन्य वर्गों के लिए पैरामीटर के रूप में 'shared_ptr' को पारित करने में समस्याएं हैं। – Tali

उत्तर

0

आप class_<UseSharedPtr, shared_ptr<UseSharedPtr>, boost::noncopyable> की जरूरत है ताकि बढ़ावा :: अजगर यह shared_ptr का उपयोग कर वस्तु का प्रबंधन करना चाहिए जानता है। यदि आप मुझे सत्यापित करना चाहते हैं तो अपना उदाहरण संकलित करें।

+0

'shared_ptr' और' noncopyable' ध्वज पहले से ही पोस्ट किए गए उदाहरण में मौजूद हैं। – Tali

0

एक आसान लेकिन बदसूरत वैकल्पिक हल Captured वर्ग के लिए enable_shared_from_this() का उपयोग करें और प्रत्येक shared_from_this() का उपयोग करके पैरामीटर के लिए एक ताजा shared_ptr प्राप्त करने के लिए किया जाएगा।

void putSharedPtr(shared_ptr<Captured> ptr) 
{ 
    s_copied = ptr->shared_from_this(); 
}