how to return numpy.array from boost::python?

后端 未结 5 2114
有刺的猬
有刺的猬 2020-11-28 08:03

I would like to return some data from c++ code as a numpy.array object. I had a look at boost::python::numeric, but its documentation is very terse

5条回答
  •  孤城傲影
    2020-11-28 08:49

    A solution that doesn't require you to download any special 3rd party C++ library (but you need numpy).

    #include  // ensure you include this header
    
    boost::python::object stdVecToNumpyArray( std::vector const& vec )
    {
          npy_intp size = vec.size();
    
         /* const_cast is rather horrible but we need a writable pointer
            in C++11, vec.data() will do the trick
            but you will still need to const_cast
          */
    
          double * data = size ? const_cast(&vec[0]) 
            : static_cast(NULL); 
    
        // create a PyObject * from pointer and data 
          PyObject * pyObj = PyArray_SimpleNewFromData( 1, &size, NPY_DOUBLE, data );
          boost::python::handle<> handle( pyObj );
          boost::python::numeric::array arr( handle );
    
        /* The problem of returning arr is twofold: firstly the user can modify
          the data which will betray the const-correctness 
          Secondly the lifetime of the data is managed by the C++ API and not the 
          lifetime of the numpy array whatsoever. But we have a simple solution..
         */
    
           return arr.copy(); // copy the object. numpy owns the copy now.
      }
    

    Of course you might write a function from double * and size, which is generic then invoke that from the vector by extracting this info. You could also write a template but you'd need some kind of mapping from data type to the NPY_TYPES enum.

提交回复
热议问题