Return 来自 Python 的 ndarray - 扩展到 C
Return ndarray from Python-extension to C
我有一个 C 程序,我从中调用了一个 Python 函数。我希望这个 Python 函数到 return 一个 ndarray,然后我可以在我的 C 代码中使用它。我需要一个 ndarray,因为我想要 Python 代码来录制声音并使用 sounddevice.record() 将数组发送回 C 代码。目前我正在使用 PyArrayObject* 作为我接收的变量类型 (pValue)。但我得到的输出都是零。我已经尝试过这个程序来接收整数并且它确实有效,所以它特别是传递数组的问题所在。
C 代码
#include <stdio.h>
#include <Python.h>
#include <numpy/ndarrayobject.h>
int main(){
PyObject *pName, *pModule, *pFunc;
PyArrayObject *pValue;
Py_Initialize();
import_array();
pName = PyString_FromString("audioPipe");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule == NULL) printf("its null\n");
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "recordSound");
if (pFunc && PyCallable_Check(pFunc)) {
pValue = PyObject_CallObject(pFunc, NULL);
for(int r = 0; r < 10; r++){printf("%f\n", pValue[r]);}
if (pValue == NULL) {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \n");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \n");
return 1;
}
Py_Finalize();
return 0;
}
Python代码(在文件audioPipe.py中)
import sounddevice as sd
fs = 44100
channels = 2
def recordSound():
recArray = np.arange(20)
print recArray
print type(recArray)
return recArray
输出
PYTHONPATH=. ./audioPassing
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
<type 'numpy.ndarray'>
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
我终于找到了使用数组的方法。我将其转换为 npy_float** 类型。 (二维,我的应用程序所必需的)使用 PyArray_AsCarray() 函数。
从那时起你就可以使用它了。更大的问题主要是我的 printstatement。我使用了错误的格式导致它被读取错误。另一个重要注意事项是,要使用 PyArray_AsCArray 函数,您应该使用 PyArray_Descr* 而不是 typenum。否则你会得到一个分段错误。
PyArray_Descr *descr;
descr = PyArray_DescrFromType(PyArray_TYPE(pValue));
if (PyArray_AsCArray(&pValue, (void*)&array, PyArray_DIMS(pValue), PyArray_NDIM(pValue), descr) < 0) {
PyErr_SetString(PyExc_TypeError, "error converting to c array");
return NULL;
}
重要的是,如果你想把它打印出来,你需要使用 as 格式。
printf("datapoint: %"NPY_FLOAT_FMT"\n", array[][]);
我有一个 C 程序,我从中调用了一个 Python 函数。我希望这个 Python 函数到 return 一个 ndarray,然后我可以在我的 C 代码中使用它。我需要一个 ndarray,因为我想要 Python 代码来录制声音并使用 sounddevice.record() 将数组发送回 C 代码。目前我正在使用 PyArrayObject* 作为我接收的变量类型 (pValue)。但我得到的输出都是零。我已经尝试过这个程序来接收整数并且它确实有效,所以它特别是传递数组的问题所在。
C 代码
#include <stdio.h>
#include <Python.h>
#include <numpy/ndarrayobject.h>
int main(){
PyObject *pName, *pModule, *pFunc;
PyArrayObject *pValue;
Py_Initialize();
import_array();
pName = PyString_FromString("audioPipe");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule == NULL) printf("its null\n");
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "recordSound");
if (pFunc && PyCallable_Check(pFunc)) {
pValue = PyObject_CallObject(pFunc, NULL);
for(int r = 0; r < 10; r++){printf("%f\n", pValue[r]);}
if (pValue == NULL) {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \n");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \n");
return 1;
}
Py_Finalize();
return 0;
}
Python代码(在文件audioPipe.py中)
import sounddevice as sd
fs = 44100
channels = 2
def recordSound():
recArray = np.arange(20)
print recArray
print type(recArray)
return recArray
输出
PYTHONPATH=. ./audioPassing
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
<type 'numpy.ndarray'>
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
我终于找到了使用数组的方法。我将其转换为 npy_float** 类型。 (二维,我的应用程序所必需的)使用 PyArray_AsCarray() 函数。 从那时起你就可以使用它了。更大的问题主要是我的 printstatement。我使用了错误的格式导致它被读取错误。另一个重要注意事项是,要使用 PyArray_AsCArray 函数,您应该使用 PyArray_Descr* 而不是 typenum。否则你会得到一个分段错误。
PyArray_Descr *descr;
descr = PyArray_DescrFromType(PyArray_TYPE(pValue));
if (PyArray_AsCArray(&pValue, (void*)&array, PyArray_DIMS(pValue), PyArray_NDIM(pValue), descr) < 0) {
PyErr_SetString(PyExc_TypeError, "error converting to c array");
return NULL;
}
重要的是,如果你想把它打印出来,你需要使用 as 格式。
printf("datapoint: %"NPY_FLOAT_FMT"\n", array[][]);