[C++-sig] How to expose to a python user defined type with to/from_python convertors?

X Wang wangx0802 at yahoo.com
Sun May 16 22:17:44 CEST 2010


How do I expose my C++ type to a user defined python type? I think I could use boost python class_<> wrapper to wrap around, but if I want to use to_python/from_python convertors?

Say I want to expose my C++ class(CA) to a python type(PA):

C++:
class CA
{
  public:
    //ctors, accessors...
  private:
    std::string name_;
    int value_;
};

Python:
class PA(object):
  def __init__(self, name, value):
    self.name=name
    self.value=value

If I use,

void initializeConverters()
{
   using namespace boost::python;
   to_python_converter<CA, CA_to_pA>();
}

with

struct CA_to_PA
{
      static PyObject* convert(CA const& s)
      {
         printf("In C++ -> python converter?\n");

         std::string name=s.name();
         int value=s.value();

#if 0
         static boost::python::object obj;
         PyObject* obj_ptr=obj.ptr();

         PyObject_SetAttrString(obj_ptr, "name", 
                PyString_FromString(name.c_str()));
         PyObject_SetAttrString(obj_ptr, "value", 
                PyInt_FromLong(value));

         return boost::python::incref(obj_ptr);
#else
         return boost::python::incref(
            //PyInt_FromLong(1999)
            Py_BuildValue("s", "native string works")
            //Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456)
            );
#endif
      }
};

How do I create a boost::python::object (or PyObject*) with "name" and "value" attributes? I could get creation and return of python native types to work, but can not get user defined types returned to the python side -- always get NoneType returned.

boost::python::object C2Py()
{
   printf("Pre assignment\n");

#if 0
   boost::python::object obj(new CA("From C++ to python", 987654321));
   PyObject* o=obj.ptr();
#else
   CA a("From C++ to python", 987654321);
   PyObject *o=CA_to_PA::convert(a);
#endif

   printf("Post assignment\n");

   PyObject *tmp=NULL;

   std::string name="No Name";
   int value=-1;

   tmp=PyObject_GetAttrString(o, "name");
   if (tmp!=NULL) name=PyString_AsString(tmp);

   tmp=PyObject_GetAttrString(o, "value");
   if (tmp!=NULL) value=PyInt_AsLong(tmp);

   printf("(%s, %d)\n", name.c_str(), value);

   return obj;
}

$ python
Python 2.5.1 (r251:54863, Oct  5 2007, 11:16:46)
[GCC 4.1.1 20070105 (Red Hat 4.1.1-53)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mytypes
>>> pa=mytypes.C2Py()
("No Name", -1)
>>>type(pa)
NoneType

Any help is appreciated, thanks!



      


More information about the Cplusplus-sig mailing list