![](/img/trans.png)
[英]Invalid pointer error whily running python in C++ using pybind11 and pytorch
[英]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.