I'm doing some testing on my C++ wrappers, and I'm hitting a point where python
just freezes. The debugger stops, no exception is thrown and my program stops
responding. I'm not entirely sure what code to show, so if it's not enough, let
me know. Here's the python code:
class HealingComponent(UseComponent): def __init__(self, FieldHealMap,
BattleHealMap = None): self.FieldHealMap = FieldHealMap
self.BattleHealMap = BattleHealMap UseComponent.__init__(self,
"HealUseModule", True, True) def Use(self, action): print
action.GetName() return False def BattleUse(self, action, field):
print "BattleTest" def Clone(self): return copy.deepcopy(self)
Action is defined as:
class Action : public Entity { public:
Action(); Action(const std::string& name, const int type
= EntityTypes::ActionEntity); std::vector<ActiveAction>
Users; std::vector<ActiveAction> Targets;
ClonePtr Clone() const override;
protected:
};
and wrapped as:
class_<Battle::Action, boost::shared_ptr<ActionWrap>, bases<Entity> >("Action")
.def(init<>()) .def(init<const
std::string&>()) .def(init<const
Battle::Action&>()) .def_readwrite("Users",
&Battle::Action::Users) .def_readwrite("Targets",
&Battle::Action::Targets) .def("Clone",
&Battle::Action::Clone, &ActionWrap::CloneDefault)
.def("__copy__", &generic__copy__< ActionWrap >)
.def("__deepcopy__", &generic__deepcopy__< ActionWrap >)
;
Entity (stripped down) is defined as:
class Entity : public Cloneable<Entity> { public: const
std::string& GetName() const;
virtual ClonePtr Clone() const override;
bool operator==(const Entity& entity) const; bool
operator!=(const Entity& entity) const; Entity& operator=(const
Entity& entity); private: std::string Name;
static int EntityIDCounter; int NameHash; int Type;
int UID; boost::unordered_map<std::string,
boost::shared_ptr<Components::Component> > ComponentCollection; };
and wrapped as:
class_<Entity, boost::shared_ptr<Entity> >("Entity")
.def("GetName", &Entity::GetName,
boost::python::return_value_policy<boost::python::reference_existing_object>())
.def("Clone", &Entity::Clone)//,
&EntityWrap::CloneDefault) .def("__eq__",
&Entity::operator ==) .def("__neq__",
&Entity::operator !=) .def("__copy__",
&generic__copy__<Entity>) .def("__deepcopy__",
&generic__deepcopy__<Entity>) ;Finally, action is
passed in as follows:
bool UseComponentWrap::Use(Battle::Action* action) {
return call_method<bool>(self, "Use", ptr(action));//,
boost::ref(Targets)); }
and from my main:
Battle::Action act = Battle::Action("Test"); if
(healertrue != nullptr) {
healertrue->Use(&act); }
the program freezes on action.GetName() in the python file. In fact, it freezes
on any attempt to access action's properties. If I don't attemp to access
action, the fuction appears to operate correctly. With no exception to catch
and no error message, I'm pretty stuck of what is causing this. It'd seem
theres a problem wrapping my Action class, but I can't see any errors there.
When I trace through with my debugger, GetName from Entity is definitely
getting called correctly.
When I trace the caller of GetName its being called from
template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N,
class AC)>inline PyObject* invoke(invoke_tag_<false,true>, RC const& rc, F& f,
TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ){ return rc(
(tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );}
in invoke.hpp. Continuin the step through, it goes into to_python_indirect.hpp
struct to_python_indirect{ template <class U> inline PyObject*
operator()(U const& ref) const { return
this->execute(const_cast<U&>(ref), is_pointer<U>()); }
on this->execute, if I step over, it immediately takes me into errors.cpp
catch(const boost::python::error_already_set&) { // The python error
reporting has already been handled. }
to be exact, I can trace the error's origin to his code segment:
BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const{ if
(this->m_class_object == 0) { ::PyErr_Format(
PyExc_TypeError , const_cast<char*>("No Python class registered for
C++ class %s") , this->target_type.name());
throw_error_already_set(); } return this->m_class_object;}when i
check this->target_type, it appears as
_M_d_name = 0x00745d88
".?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@"
so it seems as though string isn't in the registry? and the error gets digested
silently. This is really weird and I don't quite understand why returning a
string causing a problem. Is it because it's returned as a const std::string&?
I'm almost positive I've returned that type before in another program without a
problem. Could there be something wrong with action? it'd seem weird I can call
member functions on if it's not exposed correctly, but I really don't know.
If someone can help me out I'd appreciate it.
Thanks
Thanks. _______________________________________________
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig