[C++-sig] Python freezing

Jay Riley super24bitsound at hotmail.com
Fri Nov 11 03:46:37 CET 2011


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 at DU?$char_traits at D@std@@V?$allocator at 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. 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20111110/ab335a74/attachment-0001.html>


More information about the Cplusplus-sig mailing list