我正在尝试使用 pybind11 绑定如下所示的结构
struct myStruct {
int na;
int nb;
double* a;
double* b;
}
我不确定正确的方法。pybind11 文档中的示例演示如何将缓冲区协议语义附加到对象,而不是附加到类成员。
我无法更改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
嘿,很可能不是最优雅的答案,但也许它为您提供了一个起点和临时解决方案。我认为您需要做的是使用共享指针。
根据 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);
}