我正在尝试使用pybind11绑定一个看起来像这样的结构
struct myStruct {
int na;
int nb;
double* a;
double* b;
}
我不确定执行此操作的正确方法。 pybind11 documentation中的示例显示了如何将缓冲区协议语义附加到对象,而不附加到类成员。
我无法将myStruct
的接口更改为包含std::vector
,这使我可以使用通常的.def_readwrite()
。
我试图做这样的事情
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);)}
)
哪个可以编译,但是在python中我看不到基础数据中的更改会持续存在
print(my_struct.a[0]) # prints 0.0
my_struct.a[0] = 123.0
print(my_struct.a[0]) # still prints 0.0
答案 0 :(得分:0)
最有可能不是最优雅的答案,但是也许它为您提供了一个起点和临时解决方案。我认为您需要做的是使用共享指针。
在https://github.com/pybind/pybind11/issues/1150下,有人提出了类似的要求,但我无法使其适应您的示例,而对您的结果却没有改变,只是得到了相同的结果。
在您的特定示例中,对我有用的是使用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);
}