将ndarray从Python扩展名返回到C [英] Return ndarray from Python-extension to C

查看:71
本文介绍了将ndarray从Python扩展名返回到C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C程序,在这里我可以调用Python函数.我希望这个Python函数返回一个ndarray,然后可以在我的C代码中使用它.我需要一个ndarray,因为我想用Python代码记录声音并使用sounddevice.record()将数组发送回C代码.目前,我正在使用PyArrayObject *作为接收的变量类型(pValue).但是我得到的输出都是零.我已经尝试过使用该程序来接收整数,并且确实可以正常工作,所以特别是在传递数组的问题所在.

I have a C-program from where I call a Python function. I want this Python function to return a ndarray which I then could use in my C code. I need a ndarray, as I want to the Python code to record a sound and send the array back to the C code using sounddevice.record(). At the moment I am using PyArrayObject* as the variable type with which I am receiving (pValue). But all I get at the output are Zero's. I already tried this program for receiving integers and this does work, so it is specifically with passing array's where the problem lies.

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文件中)

Python Code (in file 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()函数.从那时起,您就可以使用它了.更大的问题主要是我的打印陈述.我使用了错误的格式,导致读取错误.另一个重要说明是,要使用PyArray_AsCArray函数,应使用PyArray_Descr *而不是typenum.否则,您会遇到细分错误.

I finally found a way to use the array. I converted it to a npy_float** type. (2 dimensional, necessary for my application) using the PyArray_AsCarray() function. From then on you can use it. The bigger problem was mainly with my printstatement. I used the wrong format which caused it to be read wrong. Another important note is, to use the PyArray_AsCArray function you should use PyArray_Descr* instead of a typenum. Otherwise you get a segmentation fault.

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;
}

重要的是,如果要打印出来,则需要使用它作为格式.

Important is, if you want to print it out you need to use as format.

printf("datapoint: %"NPY_FLOAT_FMT"\n", array[][]);

这篇关于将ndarray从Python扩展名返回到C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆