10

我想从 Python 调用我的 C 函数,以便操作一些 NumPy 数组。函数是这样的:

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

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

但是我得到 "Python objects cannot be cast to pointers of primitive types"输出分配的错误。我该如何做到这一点?

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

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)

但是我可以通过调用者不必预先分配适当大小的输出数组的方式来做到这一点吗?

4

2 回答 2

5

您应该在分配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
于 2012-04-10T08:09:25.743 回答
1

这是一个如何使用 C/C++ 编写的代码通过 ctypes 操作 NumPy 数组的示例。我用 C 语言编写了一个小函数,从第一个数组中取出数字的平方并将结果写入第二个数组。元素的数量由第三个参数给出。此代码被编译为共享对象。

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 加载库并调用该函数。数组指针是从 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-library,您只需要知道要传递哪些参数类型,可能使用 ctypes 在 python 中重建 c-structs。

于 2012-04-08T17:03:48.173 回答