使用C语言中的数据缓冲区和NumPy数组之间的转换来为Python接口打包C程序的最佳方法是什么?

5 c python swig numpy

我们有一个用C/C++编写的预先存在的大型成像库,具有预先存在的图像类型.我们想将它与Python接口.我们知道如何使用SWIG做大多数事情,但我们希望我们的界面使用NumPy而不是本土结构类型来存储我们的图像.

有没有人有一个例子如何做到这一点?网上有一些例子可以将NumPy与裸指针联系起来.我们如何将NumPy与现有的C类型结构接口,如下所示:

typedef struct xvimage {

    int nx, ny, nz, nt ; // dimensions

    enum {PIX_UINT8, PIX_INT16, PIX_UINT16, PIX_INT32, PIX_FLOAT, PIX_DOUBLE} ; // type

    void *data;

} xvimage;
Run Code Online (Sandbox Code Playgroud)

Tri*_*ion 0

基本上有以下三种方式:

  1. 从图像缓冲区复制到 NumPy 数组,反之亦然。当给定 C/C++ 图像时,创建一个 NumPy 数组并复制数据,当给定一个 NumPy 数组时,创建一个 C/C++ 图像并复制数据。

  2. NumPy 数组作为 C 数据指针的包装器。创建一个 NumPy 数组,但具有给定的数据指针。确保保存数据指针的 C/C++ 映像的寿命比 NumPy 数组的寿命长。NumPy 数组的寿命可以更短,因为在这种情况下它不会尝试删除数据。

  3. C/C++ 图像缓冲区作为 NumPy 数组指针的包装器。创建一个 NumPy 数组并提取数据指针,然后使用它就地操作 NumPy 数组。通过保存 Python 引用来确保 NumPy 数组的寿命足够长。

其中每一个都可以在 SWIG 类型映射中实现。

在任何情况下,您都需要将类型转换为 NumPy 类型(NPY_UINT8,..)并将图像尺寸存储在npy_intp *.

要创建 NumPy 数组,请使用PyArray_Newor PyArray_SimpleNewor PyArray_SimpleNewFromData( Array API ) 并指定所需的标志,例如 Fortran 风格的连续标志或任何对您方便的标志。您可以使用PyArray_New和提供您自己的数据指针PyArray_SimpleNewFromData

返回值是 a PyObject*,可以安全地转换为PyArrayObject*(或之前执行 a ),并且数据指针由(Array APIPyArray_Check )提取,该指针返回 a ,然后您可以将其转换为所需的类型。然后您可以根据需要执行复制或就地修改。PyArray_DATAvoid *

要添加对 Python 对象的引用,请使用Py_INCREFPy_DECREF( doc ),以防您想避免 NumPy 数组过早被删除。

如果您想在 Python 对象即将被垃圾回收时收到通知,请使用弱引用PyWeakref_NewRefdoc)。