受python保护的析构函数问题 名称空间测试 { 班级活动 { 公众: 枚举类型{BEGIN=0,RESULT,END}; 类型get_Type()const{return m_Type;} 受保护的: 事件(){} ~Event(){} m_型; }; 类EventBegin:公共事件 { 公众: EventBegin(){m_type=Event::BEGIN;} ~EventBegin(){} }; 类EventResult:公共事件 { 公众: EventResult(int-result){m_-type=Event::result;m_-result=result;} ~EventResult(){} int get_result(){return m_result;} 受保护的: int m_结果; }; 类EventEnd:公共事件 { 公众: EventEnd(){m_type=Event::END;} ~EventEnd(){} }; 类EventListener { 公众: 事件上的虚拟无效(常量事件和事件)=0; }; 结构EventListenerWrap:EventListener,py::wrapper { 无效的 on_事件(常量事件和事件) { 此->获取覆盖(“在事件上”)(事件); } }; BOOST_PYTHON_模块(test_py) { { py::scope outer=py::class_u(“Event”,py::no\u init) .add_属性(“事件类型”和事件::get_类型); py::enum_uzy(“EventType”) .value(“开始”,事件::开始) .value(“结果”,事件::结果) .value(“结束”,事件::结束) .export_值(); } { py::class_u(“EventBegin”); } { py::class_u(“EventResult”,py::no_init) .def(py::init((py::arg(“结果”)) .add_属性(“result”、&EventResult::get_result); } { py::class_u(“EventEnd”); } { py::类(“EventListener”,py::no_init) .def(“on_事件”,py::pure_虚拟(&EventListener::on_事件)); } } }
我在事件基类中有一个受保护的构造函数和析构函数,不能更改它。 在Python 2.7中,我需要从EnviistListNER类派生,并将指针发送回C++代码。 在编译过程中,我遇到了如下错误:受python保护的析构函数问题 名称空间测试 { 班级活动 { 公众: 枚举类型{BEGIN=0,RESULT,END}; 类型get_Type()const{return m_Type;} 受保护的: 事件(){} ~Event(){} m_型; }; 类EventBegin:公共事件 { 公众: EventBegin(){m_type=Event::BEGIN;} ~EventBegin(){} }; 类EventResult:公共事件 { 公众: EventResult(int-result){m_-type=Event::result;m_-result=result;} ~EventResult(){} int get_result(){return m_result;} 受保护的: int m_结果; }; 类EventEnd:公共事件 { 公众: EventEnd(){m_type=Event::END;} ~EventEnd(){} }; 类EventListener { 公众: 事件上的虚拟无效(常量事件和事件)=0; }; 结构EventListenerWrap:EventListener,py::wrapper { 无效的 on_事件(常量事件和事件) { 此->获取覆盖(“在事件上”)(事件); } }; BOOST_PYTHON_模块(test_py) { { py::scope outer=py::class_u(“Event”,py::no\u init) .add_属性(“事件类型”和事件::get_类型); py::enum_uzy(“EventType”) .value(“开始”,事件::开始) .value(“结果”,事件::结果) .value(“结束”,事件::结束) .export_值(); } { py::class_u(“EventBegin”); } { py::class_u(“EventResult”,py::no_init) .def(py::init((py::arg(“结果”)) .add_属性(“result”、&EventResult::get_result); } { py::class_u(“EventEnd”); } { py::类(“EventListener”,py::no_init) .def(“on_事件”,py::pure_虚拟(&EventListener::on_事件)); } } },python,c++,python-2.7,boost,boost-python,Python,C++,Python 2.7,Boost,Boost Python,我在事件基类中有一个受保护的构造函数和析构函数,不能更改它。 在Python 2.7中,我需要从EnviistListNER类派生,并将指针发送回C++代码。 在编译过程中,我遇到了如下错误: namespace test_py { class Event { public: enum Type { BEGIN = 0, RESULT, END }; Type get_type( ) const { return m_type; } protected: Event
namespace test_py
{
class Event
{
public:
enum Type { BEGIN = 0, RESULT, END };
Type get_type( ) const { return m_type; }
protected:
Event( ) { }
~Event( ) { }
Type m_type;
};
class EventBegin : public Event
{
public:
EventBegin( ) { m_type = Event::BEGIN; }
~EventBegin( ) {}
};
class EventResult : public Event
{
public:
EventResult( int result ) { m_type = Event::RESULT; m_result = result; }
~EventResult( ) {}
int get_result( ) { return m_result; }
protected:
int m_result;
};
class EventEnd : public Event
{
public:
EventEnd( ) { m_type = Event::END; }
~EventEnd( ) {}
};
class EventListener
{
public:
virtual void on_event( const Event& event ) = 0;
};
struct EventListenerWrap: EventListener, py::wrapper< EventListener >
{
void
on_event( const Event& event )
{
this->get_override( "on_event" )( event );
}
};
BOOST_PYTHON_MODULE( test_py )
{
{
py::scope outer = py::class_< Event, boost::noncopyable >( "Event", py::no_init )
.add_property( "event_type", &Event::get_type );
py::enum_< Event::Type >( "EventType" )
.value( "BEGIN", Event::BEGIN )
.value( "RESULT", Event::RESULT )
.value( "END", Event::END )
.export_values( );
}
{
py::class_< EventBegin, py::bases< Event > >( "EventBegin" );
}
{
py::class_< EventResult, py::bases< Event > >( "EventResult", py::no_init )
.def( py::init< int >( ( py::arg( "result" ) ) ) )
.add_property( "result", &EventResult::get_result );
}
{
py::class_< EventEnd, py::bases< Event > >( "EventEnd" );
}
{
py::class_< EventListenerWrap, boost::noncopyable >( "EventListener", py::no_init )
.def( "on_event", py::pure_virtual( &EventListener::on_event ) );
}
}
}
/boost/python/detail/destroy.hpp:static void boost::python::detail::value_destrover::execute(const volatile T*)[with T=test_py::Event]的实例化中:
/boost/python/detail/destroy.hpp:95:36:来自“void boost::python::detail::destroy_referent_impl(void*,T&(*)())[with T=const test_py::Event]的必填项”
/boost/python/detail/destroy.hpp:101:39:来自“void boost::python::detail::destroy_referent(void*,T(*)())[with T=const test_py::Event&]的必填项
/boost/python/converter/rvalue_from_python_data.hpp:135:71:boost::python::converter::rvalue_from_python_data::~rvalue_from_python_data()
/boost/python/converter/arg_from_python.hpp:107:8:required from'PyObject*boost::python::detail::caller_arity::impl::operator()(PyObject*,PyObject*)[带F=void(test_py::EventListener::*)(const test_py::Event&);Policies=boost::python::default_调用策略;Sig=boost::mpl::vector3;PyObject='
/boost/python/object/py_function.hpp:38:33:必须来自“PyObject*boost::python::objects::caller\u py_function\u impl::operator()(PyObject*,PyObject*)[with caller=boost::python::detail::caller;PyObject=\u object]”
EventListener.cpp:193:1:此处为必填项
EventListener.cpp:18:5:错误:“test_py::Event::~Event()”受保护
~Event(){}
^
在/boost/python/converter/rvalue_from_python_data.hpp:10:0包含的文件中,
从/boost/python/converter/registry.hpp:9,
从/boost/python/converter/registed.hpp:8,
从/boost/python/object/make_instance.hpp:10,
从/boost/python/object/make_ptr_instance.hpp:8,
from/boost/python/to_python_indirect.hpp:11,
从/boost/python/converter/arg_到_python.hpp:10,
from/boost/python/call.hpp:15,
从/boost/python/object_core.hpp:14,
从/boost/python/object/class.hpp:9,
从/boost/python/class.hpp:13,
自.././defs.hpp:6,
从../defs.hpp:3,
从defs.hpp:3,
来自EventListener.cpp:1:
/boost/python/detail/destroy.hpp:33:9:错误:在此上下文中
p->~T();
^
公开函数时,Boost.Python将为每个参数生成转换器。对于类型为T
和T&
的参数,生成的Python转换器将保存对象的副本,因此需要访问副本构造函数和析构函数。此行为的基本原理是防止意外暴露悬空引用。将C++参数传递给Python时也是如此。
在以下情况下,此行为会出现问题:
- 将
作为Boost公开。Python正在尝试创建一个对象,该对象将保存EventListener::on_event(const event&)
事件的副本。若要解决此问题,请考虑公开一个接受<代码>事件*/COD>的辅助函数,然后将其委托给原始函数。
- 在
中将EventListenerWrap::on_Event
对象传递给Python。要解决这个问题,请考虑在<代码> Boo::ReF()/代码>或<代码> Boo::PtRo::/Trave> /Cult>事件
struct EventListenerWrap
:EventListener,
boost::python::wrapper
{
事件无效(常量事件和事件)
{
这
/boost/python/detail/destroy.hpp: In instantiation of ‘static void boost::python::detail::value_destroyer<false>::execute(const volatile T*) [with T = test_py::Event]’:
/boost/python/detail/destroy.hpp:95:36: required from ‘void boost::python::detail::destroy_referent_impl(void*, T& (*)()) [with T = const test_py::Event]’
/boost/python/detail/destroy.hpp:101:39: required from ‘void boost::python::detail::destroy_referent(void*, T (*)()) [with T = const test_py::Event&]’
/boost/python/converter/rvalue_from_python_data.hpp:135:71: required from ‘boost::python::converter::rvalue_from_python_data<T>::~rvalue_from_python_data() [with T = const test_py::Event&]’
/boost/python/converter/arg_from_python.hpp:107:8: required from ‘PyObject* boost::python::detail::caller_arity<2u>::impl<F, Policies, Sig>::operator()(PyObject*, PyObject*) [with F = void (test_py::EventListener::*)(const test_py::Event&); Policies = boost::python::default_call_policies; Sig = boost::mpl::vector3<void, test_py::EventListener&, const test_py::Event&>; PyObject = _object]’
/boost/python/object/py_function.hpp:38:33: required from ‘PyObject* boost::python::objects::caller_py_function_impl<Caller>::operator()(PyObject*, PyObject*) [with Caller = boost::python::detail::caller<void (test_py::EventListener::*)(const test_py::Event&), boost::python::default_call_policies, boost::mpl::vector3<void, test_py::EventListener&, const test_py::Event&> >; PyObject = _object]’
EventListener.cpp:193:1: required from here
EventListener.cpp:18:5: error: ‘test_py::Event::~Event()’ is protected
~Event( ) { }
^
In file included from /boost/python/converter/rvalue_from_python_data.hpp:10:0,
from /boost/python/converter/registry.hpp:9,
from /boost/python/converter/registered.hpp:8,
from /boost/python/object/make_instance.hpp:10,
from /boost/python/object/make_ptr_instance.hpp:8,
from /boost/python/to_python_indirect.hpp:11,
from /boost/python/converter/arg_to_python.hpp:10,
from /boost/python/call.hpp:15,
from /boost/python/object_core.hpp:14,
from /boost/python/object/class.hpp:9,
from /boost/python/class.hpp:13,
from ../../defs.hpp:6,
from ../defs.hpp:3,
from defs.hpp:3,
from EventListener.cpp:1:
/boost/python/detail/destroy.hpp:33:9: error: within this context
p->~T();
^
py::scope outer = py::class_< Event, boost::noncopyable >( "Event", py::no_init )
.add_property( "event_type", &Event::get_type );
#include <memory>
namespace test_py
{
class Event
{
public:
enum Type { BEGIN = 0, RESULT, END };
Type get_type( ) const { return m_type; }
protected:
Event( ) { }
~Event( ) { }
Type m_type;
};
class EventBegin : public Event
{
public:
EventBegin( ) { m_type = Event::BEGIN; }
~EventBegin( ) {}
};
class EventResult : public Event
{
public:
EventResult( int result ) { m_type = Event::RESULT; m_result = result; }
~EventResult( ) {}
int get_result( ) { return m_result; }
protected:
int m_result;
};
class EventEnd : public Event
{
public:
EventEnd( ) { m_type = Event::END; }
~EventEnd( ) {}
};
class EventProxy
{
// define an interface for turning a non-polymorphic event
// into a polymorphic one
struct concept
{
virtual const Event* as_event() const = 0;
virtual ~concept() = default;
};
// define a model to support the polymorphic interface for a
// non-polymorphic concrete object
template<class T> struct model : concept
{
template<class...Args> model(Args&&... args)
: _event(std::forward<Args>(args)...)
{}
const Event* as_event() const override {
return &_event;
}
T _event;
};
// construct the model that contains any Event
template<class T>
EventProxy(std::shared_ptr<T> ptr)
: _impl(std::move(ptr))
{}
public:
// T should be derived from Event...
template<class T, class...Args>
static EventProxy create(Args&&... args)
{
return EventProxy(std::make_shared<model<T>>(std::forward<Args>(args)...));
}
// simply return the address of the internal non-polymorphic event
const Event* as_event() const {
return _impl->as_event();
}
// return a shared pointer that points to the internal Event BUT
// defers lifetime ownership to our internal shared_ptr to
// our model. This means we never invoke the polymorphic
// destructor of Event through the protected interface.
std::shared_ptr<const Event> as_shared_event() const {
return std::shared_ptr<const Event>(_impl, _impl->as_event());
}
private:
// lifetime of the proxy is owned by this shared_ptr.
std::shared_ptr<concept> _impl;
};
}
// a quick test.
auto main() -> int
{
auto ep = test_py::EventProxy::create<test_py::EventBegin>();
const test_py::Event* p = ep.as_event();
std::shared_ptr<const test_py::Event> sp = ep.as_shared_event();
}