Boost logo

Boost :

From: John Hunter (jdhunter_at_[hidden])
Date: 2001-12-11 22:09:44


I have two classes, Name and Person, which I have exposed to python.
Person takes a shared_ptr<Name> in it's constructor.

class Person {
public:
    Person( boost::shared_ptr<Name> pName, unsigned short age) ...
    ...
};

I would like to be able to pass instances of 'Name' created in python
to the Person constructor, i.e.,

>>> from Person import Person, Name
>>> n = Name("John", "D", "Hunter", "Ph.D")
>>> p = Person( n, 33)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: Object of extension class 'Name' does not wrap <4Name>.

But this fails because n is an instance of Name, not a
shared_ptr<Name>. I suspect there is some to_python/from_python magic
that would enable me to do this, but am not sure. Is this possible?
Does it even make sense to try?

Thanks,
John Hunter

boost_1_26_0

#include <string>
#include <sstream>
#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/python/class_builder.hpp>

class Name;
typedef boost::shared_ptr<Name> PtrName;

namespace python = boost::python;

class Name {
public:
  Name( const std::string& first,
        const std::string& middle,
        const std::string& last,
        const std::string& letters = "") :
    first(first), middle(middle), last(last), letters( letters) {}
  
  
  std::string get_first() const { return first;}
  std::string get_last() const { return last;}
  std::string get_middle() const { return middle;}
  std::string get_letters() const { return letters;}
  std::string get_full_name() const {
    std::ostringstream os;
    os << first << " "
       << middle << " "
       << last;
    if (letters.size() > 0)
      os << ", " << letters;
    os << std::ends;
    return os.str();
  }
private:
  std::string first, middle, last, letters;
};

class Person;
typedef boost::shared_ptr<Person> PtrPerson;

class Person {
public:
  Person(PtrName pName,
         unsigned short age) : pName(pName), age(age) {}
  PtrName get_name() const { return pName;}
  unsigned short get_age() const { return age;}
  void happy_birthday() { ++age;}
  void print() const {
    std::cout << pName->get_full_name()
              << " is " << age << " years old." << std::endl;}
private:
  PtrName pName;
  unsigned short age;
};

class NamePy : public python::class_builder<Name>
{
public:
  NamePy(python::module_builder&, const std::string& className);
};

NamePy::NamePy(python::module_builder& m, const std::string& className)
  : python::class_builder<Name>(m, className.c_str())
{
  def(python::constructor<std::string,std::string,std::string,std::string>());
  def(&Name::get_first, "get_first");
  def(&Name::get_middle, "get_middle");
  def(&Name::get_last, "get_last");
  def(&Name::get_letters, "get_letters");
}

class PersonPy : public python::class_builder<Person>
{
public:
  PersonPy(python::module_builder&, const std::string& className);
};

PersonPy::PersonPy(python::module_builder& m, const std::string& className)
  : python::class_builder<Person>(m, className.c_str())
{
  def(python::constructor<PtrName, unsigned short>());
  def(&Person::get_name, "get_name");
  def(&Person::get_age, "get_age");
  def(&Person::happy_birthday, "happy_birthday");
  def(&Person::print, "whois");
}

BOOST_PYTHON_MODULE_INIT(Person)
{
  
  boost::python::module_builder m( "Person" );
  
  PersonPy person( m, "Person" );
  NamePy name( m, "Name" );
  
}

  


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk