2011-08-02 19 views
8

Obecny boost :: python przykład do tłumaczenia konkretnego C wyjątek ++ do pytona idzie tak:Uogólnione tłumaczenie wyjątek dla doładowania pytona

void translate (const MyException& e) { 
    PyErr_SetString(PyExc_RuntimeError, e.what()); 
} 

boost::python::register_exception_translator<MyException>(translate); 

Niestety, wymaga to piszemy określoną funkcję do każdego wyjątkami . Staraliśmy się uprościć to, pisząc uogólniony wyjątku Tłumacz:

#include <boost/python.hpp> 

// Generalized exception translator for Boost Python 
template <typename T> struct GeneralizedTranslator { 

    public: 

    void operator()(const T& cxx_except) const { 
     PyErr_SetString(m_py_except, cxx_except.what()); 
    } 

    GeneralizedTranslator(PyObject* py_except): m_py_except(py_except) { 
     boost::python::register_exception_translator<T>(this); 
    } 

    GeneralizedTranslator(const GeneralizedTranslator& other): m_py_except(other.m_py_except) { 
     //attention: do not re-register the translator! 
    } 

    private: 

    PyObject* m_py_except; 

}; 

//allows for a simple translation declaration, removes scope problem 
template <typename T> void translate(PyObject* e) { 
    ExceptionTranslator<T> my_translator(e); 
} 

Czy to trochę pracy kodu, można zawinąć wyjątki, które implementują „co()” tak:

BOOST_PYTHON_MODULE(libtest) 
{ 
    translate<std::out_of_range>(PyExc_RuntimeError); 
} 

Niestety, wydaje się, boost :: python wywoła "tłumaczenie" kodu w funkcji wewnątrz "boost/python/detail/translate_exception.hpp" (linia 61):

translate(e); 

W naszej uogólnionego obsługi wyjątku będzie to wezwanie do GeneralizedTranslator :: operator() i że nie będzie działać na g ++, podając:

error: ‘translate’ cannot be used as a function 

Czy jest poprawny sposób to napisać?

Odpowiedz

5

Podajesz wskaźnik this jako funkcję tłumaczenia, a to nie działa, ponieważ wskaźnik do obiektu nie może być wywołany jako funkcja. Jeśli przejdziesz przez *this, to powinno zadziałać (zauważ, że to skopiuje - skonstruuj obiekt GeneralizedTranslator). Lub możesz przenieść rejestrację z konstruktora i zadzwonić pod numer

register_exception_translator<std::out_of_range>(GeneralizedTranslator<std::out_of_range>(PyExc_RuntimeError)); 
+0

Tak. Masz to! Zaktualizowałem powyższy kod, aby pokazać właściwe rozwiązanie. Dzięki –