我在c中的结构如下
typedef struct _person{
int id[10];
int number[10];
}person;
如何使用pybind11绑定它?
答案 0 :(得分:0)
当您希望数据可写时,似乎没有一种AFAICT的好方法(当数据为只读时,它的设计要少一些)。无论如何,假设您已经安装了numpy,以下操作可以解决问题:
#include <pybind11/pybind11.h>
#include <pybind11/pytypes.h>
#include <pybind11/numpy.h>
typedef struct _person{
int id[10];
int number[10];
} person;
PYBIND11_MODULE(person, m)
{
pybind11::class_<person>(m, "person", pybind11::buffer_protocol())
.def(pybind11::init<>())
.def_property("id", [](person &p) -> pybind11::array {
auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
auto base = pybind11::array(dtype, {10}, {sizeof(int)});
return pybind11::array(
dtype, {10}, {sizeof(int)}, p.id, base);
}, [](person& p) {})
.def_property("number", [](person &p) -> pybind11::array {
auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
auto base = pybind11::array(dtype, {10}, {sizeof(int)});
return pybind11::array(dtype, {10}, {sizeof(int)}, p.number, base);
}, [](person& p) {});
}
票证将提供空的基础对象,该对象将使数组表现为视图对象。没有基础,它将复制。您不需要属性设置器(如果实现,则可以设置数组,而不是数组项),并且可能会引发错误,而不是像我那样提供无操作。另外,如果确实有两个相同大小的数组,则可以使用辅助函数代替lambda。
绑定C内置数组的基本问题是python没有正确的数组类型(有一个基本的内存视图和模块数组,但是没有真正的数组类型),因此您需要从某个地方获取一个并pybind11宁愿选择numpy的游戏,因为它是镇上最好的游戏。
只是为了向您展示一种替代方法,在cppyy(http://cppyy.org)中,我采取了另一种方法:它具有低级数组视图,随后可以将其交给numpy进行查看或根据需要进行复制,因为它实现了完整的缓冲区协议。这样做的好处是可以由python用户决定最终用途。缺点是,如果您仍然要使用numpy,那将是一个额外的步骤。但它也可以在不安装numpy的情况下直接使用:
import cppyy
cppyy.cppdef("""
typedef struct _person{
int id[10];
int number[10];
} person;
""")
p = cppyy.gbl.person()
print(len(p.id), p.id)
print(list(p.id))
产生:
(10, <cppyy.LowLevelView object at 0x105ab33b0>)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]