简体   繁体   English

带有类成员的pybind11缓冲协议

[英]pybind11 buffer protocol with class members

I'm trying to use pybind11 to bind a struct that looks like this 我正在尝试使用pybind11绑定一个看起来像这样的结构

struct myStruct {
 int na;
 int nb;
 double* a;
 double* b;
}

I'm not sure the right way to go about it. 我不确定采取正确的方法。 The examples in the pybind11 documentation show how to attach buffer protocol semantics to an object, but not to a class member. pybind11文档中的示例显示了如何将缓冲区协议语义附加到对象,而不附加到类成员。

I don't have the luxury of changing the interface of myStruct to contain std::vector s either which would allow me to use the usual .def_readwrite() . 我没有将myStruct的接口myStruct为包含std::vector的奢侈,这要么允许我使用通常的.def_readwrite()

I've tried doing something like this 我试图做这样的事情

py::class_<myStruct>(m, "myStruct")
    .def_property("a",
        [](myStruct &s) {return py::array<double>({s.na}, {sizeof(double), s.a};)},
        [](myStruct &s, py::array_t<double> val) {std::copy((double*) val.request().ptr, (double*) val.request().ptr + s.na, s.a);)}
    )

Which compiles, but in python I don't see changes persist in the underlying data 哪个可以编译,但是在python中我看不到基础数据中的更改仍然存在

print(my_struct.a[0]) # prints 0.0
my_struct.a[0] = 123.0
print(my_struct.a[0]) # still prints 0.0

Hey most likely not the most elegant answer, but maybe it gives you a starting point and temporary solution. 嘿,很可能不是最优雅的答案,但也许它为您提供了一个起点和临时解决方案。 I think what you need to do is use shared pointers. 我认为您需要做的是使用共享指针。

Under https://github.com/pybind/pybind11/issues/1150 someone asked something similar but I was not able to adapt it to your example and only got the same result to yours with no changes to the data. https://github.com/pybind/pybind11/issues/1150下,有人提出了类似的要求,但我无法将其适应您的示例,并且只对您的示例获得了相同的结果,而数据却没有变化。

What worked for me in your specific example was using the shared_ptr and defining setter and getter functions for the pointers with a simple def_property for the pybin11 class. 在您的特定示例中,对我有用的是使用shared_ptr并为指针定义了setter和getter函数,并对pybin11类使用了简单的def_property。

class class_DATA{
    public: 
        int na;
        std::shared_ptr<double> a;  

        void set_a(double a){*class_DATA::a = a; };
        double get_a(void){return *class_DATA::a; };
};

PYBIND11_MODULE(TEST,m){
  m.doc() = "pybind11 example plugin";
 //the costum class
 py::class_<class_DATA>(m, "class_DATA", py::dynamic_attr())
  .def(py::init<>())    //needed to define constructor
  .def_readwrite("na", &class_DATA::na)
  .def_property("a", &class_DATA::get_a, &class_DATA::set_a, py::return_value_policy::copy);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM