如何将原始指针传递给 Boost.Python?

发布于 2024-12-15 02:28:42 字数 680 浏览 1 评论 0原文

我正在尝试使用 Boost.Python 作为 C++ 函数的包装器,该函数接收指针、修改数据(例如在 Python 端作为 numpy 数组进行管理)并返回。如何让 Python numpy 和 Boost.Python 协作并为我提供函数内的原始指针?

#include <boost/python.hpp>
namespace
{
  char const *greet(double *p)
  {
    *p = 2.;
    return "hello world";
  }
}
BOOST_PYTHON_MODULE(module)
{
  boost::python::def("greet", &greet);
}

在Python中,当我尝试时,

import numpy as np
a = np.empty([2], dtype=np.double)
raw_ptr = a.data
print cmod.greet(raw_ptr)

我收到错误,

Boost.Python.ArgumentError: Python argument types in
<...>.module.greet(buffer)
did not match C++ signature:
greet(double*)

I'm trying to use Boost.Python as a wrapper for a C++ function that receives a pointer, modifies the data (managed on Python side as numpy array for example) and returns. How do I get Python numpy and Boost.Python to collaborate and to give me the raw pointer inside the function?

#include <boost/python.hpp>
namespace
{
  char const *greet(double *p)
  {
    *p = 2.;
    return "hello world";
  }
}
BOOST_PYTHON_MODULE(module)
{
  boost::python::def("greet", &greet);
}

In Python when I try,

import numpy as np
a = np.empty([2], dtype=np.double)
raw_ptr = a.data
print cmod.greet(raw_ptr)

I get the error,

Boost.Python.ArgumentError: Python argument types in
<...>.module.greet(buffer)
did not match C++ signature:
greet(double*)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七堇年 2024-12-22 02:28:42

安德烈亚斯·克勒克纳(Andreas Kloeckner)建议的一种似乎有效的方法,欢迎评论和替代方案。 greet() 修改如下,

char const *greet(boost::python::object obj) {
    PyObject* pobj = obj.ptr();
    Py_buffer pybuf;
    if(PyObject_GetBuffer(pobj, &pybuf, PyBUF_SIMPLE)!=-1)
    {
        void *buf = pybuf.buf;
        double *p = (double*)buf;
        *p = 2.;
        *(p+1) = 3;
        PyBuffer_Release(&pybuf);
    }
    return "hello world";
    }

在 Python 中只需使用:

print cmod.greet(a)

One way that seems to work, suggested by Andreas Kloeckner, comments and alternatives are welcome. The greet() is modified as follows,

char const *greet(boost::python::object obj) {
    PyObject* pobj = obj.ptr();
    Py_buffer pybuf;
    if(PyObject_GetBuffer(pobj, &pybuf, PyBUF_SIMPLE)!=-1)
    {
        void *buf = pybuf.buf;
        double *p = (double*)buf;
        *p = 2.;
        *(p+1) = 3;
        PyBuffer_Release(&pybuf);
    }
    return "hello world";
    }

in Python just use:

print cmod.greet(a)
假情假意假温柔 2024-12-22 02:28:42

您可能需要使用 numpy ctypes 接口来获取指向存储的原始指针,然后将 ctypes 指针设置为 double 以传递到调用中。 ndarray.data 是缓冲区类型,而不是指针。

我没有任何使用 boost.python 的经验,但我怀疑

In [28]: x=np.array([1,2,3,4],dtype=np.double)

In [29]: p=x.ctypes.data_as(ctypes.POINTER(ctypes.c_double))

In [30]: type(p)
Out[30]: <class 'ctypes.LP_c_double'>

如果传递给需要指针作为参数的包装 C++ 函数,类似的东西会起作用。

You will probably need to use the numpy ctypes interface to get a raw pointer to the storage, and then make a ctypes pointer to double to pass into the call. ndarray.data is a buffer type, not a pointer.

I don't have any experience with boost.python, but I suspect something like

In [28]: x=np.array([1,2,3,4],dtype=np.double)

In [29]: p=x.ctypes.data_as(ctypes.POINTER(ctypes.c_double))

In [30]: type(p)
Out[30]: <class 'ctypes.LP_c_double'>

will work if passed to a wrapped C++ function expecting a pointer as an argument.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文