初学者用Python扩展C(特别是Numpy)

2024-04-19 17:00:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究一个实时音频处理动态链接库,其中我有一个二维C数组的浮点数据,代表音频缓冲区。一个维度是时间(样本),另一个维度是通道。我想把它传递给一个Python脚本,作为DSP处理的一个麻木数组,然后我想把它传回到C中,这样数据就可以在C中继续进行处理链。C++中的成员函数,它的处理看起来像这样:

void myEffect::process (float** inputs, float** outputs, int buffersize)
{
    //Some processing stuff
}

数组输入输出大小相等。整数buffersize输入输出数组中的列数。在python方面,我希望通过如下函数执行处理:

^{pr2}$

现在,我的问题是,如何以最有效的方式(避免不必要的内存复制等)将数据从C中取出?到目前为止,对于简单的参数更改,我使用了如下C-API调用:

pValue = PyObject_CallMethod(pInstance, "setParameter", "(f)", value);

我对我的numpy数组使用类似的方法还是有更好的方法?谢谢你的阅读。在


Tags: 数据方法函数脚本时间成员代表数组
1条回答
网友
1楼 · 发布于 2024-04-19 17:00:36

您可以完全避免处理numpycapi。Python可以使用ctypes模块调用C代码,并且可以使用数组的ctypes属性访问numpy数据的指针。在

下面是一个最小的例子,展示了一维平方和函数的过程。在

ctsquare.c.公司

#include <stdlib.h>

float mysumsquares(float * array, size_t size) {
    float total = 0.0f;
    size_t idx;
    for (idx = 0; idx < size; ++idx) {
        total += array[idx]*array[idx];
    }
    return total;
}

编译到ctsquare.so在

这些命令行适用于OS X,您的操作系统可能会有所不同。在

^{pr2}$

ctsquare.py在

import numpy
import ctypes

# pointer to float type, for convenience
c_float_p = ctypes.POINTER(ctypes.c_float)

# load the library
ctsquarelib = ctypes.cdll.LoadLibrary("ctsquare.so")

# define the return type and arguments of the function
ctsquarelib.mysumsquares.restype = ctypes.c_float
ctsquarelib.mysumsquares.argtypes = [c_float_p, ctypes.c_size_t]

# python front-end function, takes care of the ctypes interface
def myssq(arr):
    # make sure that the array is contiguous and the right data type
    arr = numpy.ascontiguousarray(arr, dtype='float32')

    # grab a pointer to the array's data
    dataptr = arr.ctypes.data_as(c_float_p)

    # this assumes that the array is 1-dimensional. 2d is more complex.
    datasize = arr.ctypes.shape[0]

    # call the C function
    ret = ctsquarelib.mysumsquares(dataptr, datasize)

    return ret

if __name__ == '__main__':
    a = numpy.array([1,2,3,4])
    print 'sum of squares of [1,2,3,4] =', myssq(a)

相关问题 更多 >