使用pybind11从python传递指向C ++的指针

Fra*_*ank 6 c++ python pybind11

我已经使用pybind11创建了以下类:

py::class_<Raster>(m, "Raster")
        .def(py::init<double*, std::size_t, std::size_t, std::size_t, double, double, double>());
Run Code Online (Sandbox Code Playgroud)

但是我不知道如何在Python中调用此构造函数。我看到Python期望在double *位置使用浮点数,但我似乎无法调用它。

我已经尝试过,ctypes.data_as(ctypes.POINTER(ctypes.c_double))但这不起作用...

编辑:

我已经从@Sergei答案中提取了答案。

py::class_<Raster>(m, "Raster", py::buffer_protocol())
    .def("__init__", [](Raster& raster, py::array_t<double> buffer, double spacingX, double spacingY, double spacingZ) {
    py::buffer_info info = buffer.request();
    new (&raster) Raster3D(static_cast<double*>(info.ptr), info.shape[0], info.shape[1], info.shape[2], spacingX, spacingY, spacingZ);
    })
Run Code Online (Sandbox Code Playgroud)

Ser*_*gei 5

Pybind 进行自动转换。当您绑定时,f(double *)参数被假定为指向单个值的指针,而不是指向数组开始的指针,因为从 python 端期望这样的输入是非常不自然的。因此 pybind 将使用此逻辑转换参数。

如果您需要将原始数组传递给 C++,请使用py::buffer如下所示

py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
    .def("__init__", [](Matrix &m, py::buffer b) {
        typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;

        /* Request a buffer descriptor from Python */
        py::buffer_info info = b.request();

        /* Some sanity checks ... */
        if (info.format != py::format_descriptor<Scalar>::format())
            throw std::runtime_error("Incompatible format: expected a double array!");

        if (info.ndim != 2)
            throw std::runtime_error("Incompatible buffer dimension!");

        auto strides = Strides(
            info.strides[rowMajor ? 0 : 1] / (py::ssize_t)sizeof(Scalar),
            info.strides[rowMajor ? 1 : 0] / (py::ssize_t)sizeof(Scalar));

        auto map = Eigen::Map<Matrix, 0, Strides>(
            static_cast<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);

        new (&m) Matrix(map);
    });
Run Code Online (Sandbox Code Playgroud)

为了使它工作,你需要传递一个遵循 python 缓冲区协议的类型。