2013-01-16 8 views
5

Ich mag Objekte in benutzerdefinierten Smart-Pointer in Python gewickelt belichten Boost :: PythonVerwenden von benutzerdefinierten Smart-Pointer im Boost-Python

Die Einsprüche

  • bestehende Nutzung des benutzerdefinierten Smart Zeiger ist zu weit verbreitet zu wirtschaftlich auf den Boost Smart Pointer
  • Ich möchte die automatische Dereferenzierung Technik wie in mehreren Standorten beschrieben

Das Problem ist, dass ich nicht scheinen kann, es richtig zu machen. Hier ist ein Beispielcode:

LegacyCode :: Ptr -> Legacy-Smart-Pointer-Code

LegacyCode :: Session -> Legacy-Objekt, das in der alten Smart-Pointer

namespace boost { namespace python 
{ 
    template <class T> T* get_pointer(LegacyCode::Ptr<T> const& p) 
    { 
     return p.get(); 
    } 


    template <typename T> 
    struct pointee<LegacyCode::Ptr<T> > 
    { 
     typedef T type; 
    }; 

}}* 

BOOST_PYTHON_MODULE(pyro) 
{ 
    using namespace boost::python; 

    class_<LegacyCode::Session,LegacyCode::Ptr<LegacyCode::Session>>("Session") 
              .def("get_type",&LegacyCode::Session::getType); 
} 

Antwort

3

hier gewickelt ist ist ein voll funktionsfähiges Beispiel. Sie hatten es fast - Sie müssen die get_pointer() aus dem Namespace boost::python entfernen.

#include <boost/python.hpp> 

// dummy smart ptr class 
template <typename T> class Ptr { 
    public: 
    typedef T element_type; 

    Ptr(): px(0) {} 
    Ptr(T* p): px(p) {} 

    // base operators 
    T* operator->() { return px; } 
    const T* operator->() const { return px; } 
    T& operator*() { return *px; } 
    const T& operator*() const { return *px; } 

    // getters 
    T* get() { return px; } 
    const T* get() const { return px; } 

    private: 
    T* px; 
}; 

// a dummy class that will be held by your custom smart pointer 
class Session { 
    public: 
    Session(int value) : value_(value) {} 
    virtual ~Session() {} 

    // a few methods to play with the class 
    int value() const { return value_; }; 
    void value(int value) { value_ = value; } 

    private: 
    int value_; 
}; 

// this emulates methods actually using your smart pointers 
void print_value_1(const Ptr<Session>& s) { 
    std::cout << "[by const reference] The value of this session is " << s->value() << std::endl; 
} 

void print_value_2(Ptr<Session> s) { 
    std::cout << "[by value] The value of this session is " << s->value() << std::endl; 
} 

// here comes the magic 
template <typename T> T* get_pointer(Ptr<T> const& p) { 
    //notice the const_cast<> at this point 
    //for some unknown reason, bp likes to have it like that 
    return const_cast<T*>(p.get()); 
} 

// some boost.python plumbing is required as you already know 
namespace boost { namespace python { 

    template <typename T> struct pointee<Ptr<T> > { 
    typedef T type; 
    }; 

} } 

// now the module 
BOOST_PYTHON_MODULE(example) { 
    using namespace boost::python; 
    class_<Session, Ptr<Session>, boost::noncopyable>("Session", init<int>()); 
    def("print_value_1", &print_value_1); 
    def("print_value_2", &print_value_2); 
} 

Sie können dies testen mit folgendem Python-Code:

import example 
s = example.Session(27) 
example.print_value_1(s) 
example.print_value_2(s) 

Wir sind mit dem Beispiel zeigen, dass boost.python korrekt die Umwandlung laufen nach Bedarf.

+3

Um den unbekannten Grund zu beantworten, ist der 'const_cast' aufgrund der' Ptr'-Definition erforderlich, nicht wegen Boost.Python. 'Ptr' wendet' const' auf sein Element an, wenn 'Ptr' selbst' const' ist. Dies entspricht dem Unterschied zwischen const-pointer und pointer-to-const. Zum Beispiel macht 'shared_ptr' diese Unterscheidung im Typ selbst:' const shared_ptr 'und' shared_ptr '. –

+0

Ich habe derzeit das folgende Problem: Die CGAL-Bibliothek hat eine Klasse, die im Grunde einen Zeiger (Handle) umschließt. Ich möchte es enthüllen, als ob es ein normales was auch immer-der-Griff-Punkte ist. Aber leider hat das Handle keine element_type Variable und daher bekomme ich immer Kompilierfehler. Irgendwelche Hinweise? – wolfv