[C++-sig] Convert OpenCV class reference return value
Chris Schnaufer
chris.schnaufer at eagleview.com
Wed Apr 5 09:40:47 EDT 2017
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>())
;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20170405/8b2ab355/attachment.html>
More information about the Cplusplus-sig
mailing list