[C++-sig] got stuck starting with boost.python

Chris Niekel chris at niekel.net
Tue Nov 2 10:43:05 CET 2004


Hi,

I just started with boost.python, and I'm already stuck.
The C++ classes provide a 'readonly' view of the objects, and the user of
these classes can't create the objects, they're created and destroyed by some
friend-class (say, Manager).

So, there's a class Entity 
{
protected:
    Entity();
    ~Entity();

    std::string getId();
    ...
};

class Manager
{
public:
    std::map<std::string, Entity*> getEntityMap();
    ...
}

First problem was that the Entity destructor had to be public. 
So I changed that in the headerfile 
Q1: is there a better way to fix that?

I've translated the getEntityMap into a getEntities, using a new function
that creates a boost::python::list and walks through the map, adding the
elements. That works now.

What I want to do next is:

class_<Entity, Entity*>("Entity", no_init)
    .def_readonly("id", &Entity::getId)
    ;

That gives me a weird errors:
/usr/people1/smf/include/boost-1_31/boost/python/data_members.hpp:285:
conversion
   from `boost::is_member_pointer<const
   std::string&(Entity::*)() 
      const>' to non-scalar type `boost::mpl::bool_<false>' requested

which I don't understand. So working around the problem, I
    .def("id", &Entity::getId)
That also gives an error:
boost/python/detail/invoke.hpp:89: no match 
   for call to `(const 
      boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<const
         std::string&>) (const std::basic_string<char,
         std::char_traits<char>, 
            std::allocator<char> >&)'

Also beyond my comprehension. If I do:
    .def("id", &Entity::getId, return_internal_reference<>())
it compiles, but I get the runtime exception:
TypeError: No Python class registered for C++ class std::string.

So I've now created an extra method in the Entity: const char*
getIdCStr() which returns the id.c_str(). That sorta works.
I can do in python: for i in getEntities(): print i.id()

With .add_property("id", &Entity::getIdCStr) it works as I want it. 

Q2: This requires me to add methods to the Entity class (there are several
std::string attributes I need).  Is there a more elegant way to solve this?

Hope anyone can help me. I worked through the tutorial, but after jumping
to my own code, I noticed quite some bumps in my road.

Regards,
    Chris Niekel


-- 
    I've been down so long, if I'd cheer up, I'd still be depressed.
            - Lisa Simpson, Moanin' Lisa Blues.



More information about the Cplusplus-sig mailing list