[C++-sig] MillerIndex example and other notes

daniel daniel.kottow at ipk.fhg.de
Thu Oct 17 18:32:49 CEST 2002


hi,
and first of all congratulations to v2 boost.python - i feel it much 
easier to find my way around than in the previous version, specially due 
to the enhanced docs. thank you.

i would like to ask/comment some points i noticed when upgrading to v2 my 
first and certainly buggy version of a boosted c++ api:

let me start with the MillerIndex example filed in 
examples/do_it_yourself_convts.cpp of v1.
i guess this is very similar to the faq posted by ralf on c++ vs native 
python containers:
according to that, converrting MillerIndex to native python list would go 
like this:


/*************************************************************/

class MillerIndex {
  public:
    int v[3];
};

struct MillerIndex_to_python
{
   static PyObject* convert(MillerIndex const& mi)
   {
	boost::python::tuple result = make_tuple(mi.v[0],mi.v[1],mi.v[2]);
	return incref(result.ptr());
   }
}; 
struct MillerIndex_from_python
{
   MillerIndex_from_python()
   {
	boost::python::converter::registry
	  ::push_back(&convertible,&construct,
				  boost::python::type_id<MillerIndex>());
   }  
   static void* convertible(PyObject* obj_ptr)
   {
	if ( ! PySequence_Check(obj_ptr)) {
	  return 0;
	}

	if ( PySequence_Length(obj_ptr) != 3) {
	  return 0;
	}

	return obj_ptr; // if the input object is convertible
   }     
   static void construct(PyObject* obj_ptr,
						boost::python::converter
						 
::rvalue_from_python_stage1_data* data)
   {

	boost::python::tuple t = extract<boost::python::tuple>(obj_ptr);

	void* storage;
	storage = ((boost::python::converter
				 
::rvalue_from_python_storage<FloatVector>*)data)->storage.bytes;

	new (storage) MillerIndex;
	data->convertible = storage;

	MillerIndex& result = *((MillerIndex*)storage);

	for(int i=0;i<3;++i) {
	  result.v[i] = extract<int>(t[i]); //checking omitted
	}
   }
};

/*************************************************************/

IMHO this is pretty long and a bit akward, at least the from_python part.
is their a more easy way of doing this ? or is this usage of boost.python 
disencouraged ?

------

extract<>() and the object class seemed to me really nice, enhancing 
features.

i think i misunderstood the tutorial when it talks about instantiating 
class_<T> objects, though.
according to it, i thought it was necessary to write down the class_>T> 
"declaration" just as if you were exposing the class to python but finally 
calling the constructor
(http://www.boost.org/libs/python/doc/tutorial/doc/derived_object_types.html)

but if you already registered a certain class_<T> in the module,
you can instantiate python-objects from c++ of that type just by writing:
object(T()); (i tried to create an instance by "re-declaring" class_<T> in 
my code and i got a registration error at execution time, saying:

python: libs/python/src/converter/registry.cpp:74: void 
boost::python::converter::registry::insert(PyObject*(*)(const void*), 
boost::python::type_info): Assertion `slot == 0' failed

another thing which i have not really played much with is about the 
reference counting. as long as you stay in the upper levels, exporting 
classes with class_<T> and using object/tuple/list etc. this is perfectly 
hidden, very nice. but if you have to write these converter things by 
hand, i would like to know how to get them back into the "boost refernce 
counting".

e.g. if i have: 
PyObject *obj = createObjectFromTheTimesWhereBoostWasNotBorn();
{
	return Py_BuildValue("iii", 1,2,3);
}

how could i incorporate this using boost::python::def() ?


greetings, daniel

-- 
Daniel Kottow                                    daniel.kottow at ipk.fhg.de
Security and Testing Technology                  
http://vision.fhg.de/~daniel
Production Technology Centre                     Pascalstr. 8 - 9
Fraunhofer-Institut IPK Berlin                   D - 10587 Berlin






More information about the Cplusplus-sig mailing list