繁体   English   中英

在 Cython 和 NumPy 中包装 C function

[英]Wrapping C function in Cython and NumPy

我想从 Python 给我的 C function 打电话,以操纵一些 NumPy arrays。function 是这样的:

void c_func(int *in_array, int n, int *out_array);

结果在 out_array 中提供,我事先知道其大小(实际上不是我的 function)。 我尝试在相应的 .pyx 文件中执行以下操作,以便能够将输入从 NumPy 数组传递到 function,并将结果存储在 NumPy 数组中:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):    
    n = len(in_array)
    out_array = np.zeros((512,), dtype = np.int32)
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data)
    return out_array

但是对于 output 赋值,我得到"Python objects cannot be cast to pointers of primitive types"错误。 我该如何做到这一点?

(如果我要求 Python 调用者分配正确的 output 数组,那么我可以这样做

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array, np.ndarray[np.int32_t, ndim=1] out_array):  
    n = len(in_array)
    mymodule.cfunc(<int *> in_array.data, n, <int*> out_array.data)

但是我能否以调用者不必预先分配适当大小的 output 数组的方式来执行此操作?

您应该在 out_array 赋值之前添加cdef np.ndarray out_array

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):    
    cdef np.ndarray out_array = np.zeros((512,), dtype = np.int32)
    n = len(in_array)
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data)
    return out_array

下面是一个示例,说明如何通过 ctypes 使用以 C/C++ 编写的代码来操作 NumPy arrays。 我在 C 中写了一个小的 function,从第一个数组中取出数字的平方并将结果写入第二个数组。 元素的数量由第三个参数给出。 此代码编译为共享 object。

squares.c 编译为 squares.so:

void square(double* pin, double* pout, int n) {
    for (int i=0; i<n; ++i) {
        pout[i] = pin[i] * pin[i];
    }
}

在 python 中,您只需使用 ctypes 加载库并调用 function。数组指针是从 NumPy ctypes 接口获取的。

import numpy as np
import ctypes

n = 5
a = np.arange(n, dtype=np.double)
b = np.zeros(n, dtype=np.double)

square = ctypes.cdll.LoadLibrary("./square.so")

aptr = a.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
bptr = b.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
square.square(aptr, bptr, n)

print b

这适用于任何 c 库,您只需要知道要传递哪些参数类型,可能会使用 ctypes 在 python 中重建 c 结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM