[C++-sig] Re: to_python_converters with internal-ref-like management
esatel
eli at water.ca.gov
Tue Sep 14 23:22:49 CEST 2004
I am still working on Jonothan Brandmeyer's solution. I'm a beginner to the
object API, so it may take a bit.
In the meantime, is the following a bad solution to this problem? It uses a
free function in C++ as a member accessor in python, and it uses call
policies to set up the dependency that I want. Minus a few lines of
conversion details, the whole thing looks like:
// A free function
PyObject* slice_getter( multi_array_holder& holder){
subarray=holder.get_slice()
return(convert_to_numarrayptr(subarray)); //details omitted
}
// The salient part of the python wrapper
.def("get_slice", &get_the_slice,
with_custodian_and_ward_postcall<0,1>())
I have only tested this for object lifetime management. It appears to
work -- the multi_array_holder won't get destroyed while a subarray points
to it.
This solution seem to circumvent the whole to_python_converter apparatus,
which scares me a bit -- is the only downside that the code isn't reusable,
or is there other voodoo performed by to_python_converter I am going to wish
I had?
Thanks,
Eli
"esatel" <eli at water.ca.gov> wrote in message
news:chqk0r$3lq$1 at sea.gmane.org...
> Hi. I have a question about how/whether it is possible to use a
> to_python_converter and still take advantage of lifetime management using
> weak references. It is a special case, but kind of an interesting one.
>
> I have a an class called array_holder containing a large member of class
> boost::multi_array. Member functions of my array_holder class return
> sliced
> subarrays of the parent array. Because of the way multi_array works (to
> manage large objects), in C++ subarrays contain pointers to, rather than
> copies of, the underlying data from the parent array.
>
> When I wrap the array_holder class for python, I want to return subarrays
> from these methods as PyArrays. I can do this without copying any of the
> underlying data as follows (some pseudo code is included below):
> 1. The array_holder method returns by value a (new) subarray object
> containing a pointer to the (original) multi_array data.
> 2. The converter converts the subarray to a PyArray without copying the
> data -- it creates a new PyArray and points it to the same base address as
> the subarray.
>
> However, to be safe, the array_holder (which contains the multi_array
> managing the data) to last as long as the subarray. Is there a slick way
> to
> do this? I realize that I can eliminate the need for this dependence
> through
> copies, but the size of the arrays involved (slices >10000 doubles)
> motivates me to avoid the wasted motion.
>
> Thanks,
> Eli
>
>
> The following pseudo-code mimics how I do it unsafely:
>
> /* multi_array and sub_array are in Boost --
> both contain a raw char* pointer to data */
> typedef multi_array<int, 2>::array_view<2>::type subarray_type;
>
> class array_holder
> {
> public:
> subarray_type get_slice(); // creates the new subarray object,
> // sets the *data pointer of the subarray
> to
> // that of the multi_array
> }
> private:
> array_type m_multi_array();
> }
>
> struct marray_to_pyarray
> {
> static PyObject* convert(subarray_type const& a)
> {
> PyObject* po = PyArray_FromDimsAndData(2,
> (int*) a.shape(),
> PyArray_DOUBLE,
> (char*) a.origin() // point to the subarray data
> );
> return po;
> }
> };
>
> void export_array_holder(){
> import_array();
> class_<multi_array_creator>("array_holder")
> .def("slice", &array_holder::get_slice);
> to_python_converter<subarray_type, marray_to_pyarray>();
> }
>
> BOOST_PYTHON_MODULE(demo_array){
> export_array_holder();
> }
More information about the Cplusplus-sig
mailing list