| Store | Cart

Re: [C++-sig] Convert OpenCV class reference return value

From: Chris Schnaufer <chri...@eagleview.com>
Wed, 5 Apr 2017 13:40:47 +0000
I think I have been able to answer my own question. As Stephan had pointed out, it came down to the return_value_policy.

By defining the conversions (as in my last post) and using return_value_policy<return_by_value> I was able to have the translation handled appropriately when returning const Vec3d& types. The conversions also handled the case with a const Vec3d& as a parameter (and all other Vec3d references).

Many thanks to Stephan for pointing me in the right direction.

Here is the test in its final state:

#include <boost/python.hpp>
namespace p = boost::python;

class Vec3d {
                public:
                  Vec3d() {v[0] = v[1] = v[2] = 0.0;}
                  virtual ~Vec3d() {}
                  double operator[](size_t idx) const {return v[idx];}
                  double& operator[](size_t idx) {return v[idx];}
                private:
                  double v[3];
};

class UseVec3d {
                public:
                                UseVec3d() {}
                                UseVec3d(const Vec3d& vec) : v(vec) {}
                                virtual ~UseVec3d() {};
                                const Vec3d& get_vec() const {return v;}
                                void set_vec(const Vec3d& vec) {v = vec;}
                private:
                  Vec3d                 v;
};

struct vec3d_to_py {
static PyObject* convert(const Vec3d& src) {
  return Py_BuildValue("(ddd)", src[0], src[1], src[2]);
}

static PyTypeObject const *get_pytype ()  {
  return &PyTuple_Type;
}
};

struct vec3d_from_py  {
  vec3d_from_py()   {
    boost::python::converter::registry::push_back(
        &convertible,
        &construct,
        boost::python::type_id<Vec3d>()
        );
  }

  static void* convertible(PyObject* obj)   {
                                return obj;
  }

  static void construct(PyObject* self, p::converter::rvalue_from_python_stage1_data* data)   {
                typedef p::converter::rvalue_from_python_storage<Vec3d> storage_t;

                storage_t* store = reinterpret_cast<storage_t *>(data);
                void* mem = store->storage.bytes;
                new (mem) Vec3d();

                Vec3d* pv = reinterpret_cast<Vec3d *>(mem);
                PyArg_ParseTuple(self, "ddd", &((*pv)[0]), &((*pv)[1]), &((*pv)[2]));
                data->convertible = mem;
  }
};


BOOST_PYTHON_MODULE(raf)
{
                vec3d_from_py();
                p::to_python_converter<Vec3d, vec3d_to_py, true>();

                p::class_<UseVec3d>("UseVec3d")
                                .def(p::init<Vec3d>())
                                .def("get_vec", &UseVec3d::get_vec, p::return_value_policy<p::return_by_value>())
                ;
}


_______________________________________________
Cplusplus-sig mailing list
Cplu...@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig

Recent Messages in this Thread
Chris Schnaufer Apr 05, 2017 01:40 pm