簡體   English   中英

使用 pybind11 從 python 傳遞指向 C++ 的指針

[英]passing pointer to C++ from python using pybind11

我使用 pybind11 創建了以下類:

py::class_<Raster>(m, "Raster")
        .def(py::init<double*, std::size_t, std::size_t, std::size_t, double, double, double>());

但是我不知道如何在 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);
    })

Pybind 進行自動轉換。 當您綁定f(double *)時,假定參數是指向單個值的指針,而不是指向數組 begin 的指針,因為從 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);
    });

要使其工作,您需要傳遞一個遵循 python 緩沖區協議的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM