从C发送双精度数组到Python并返回

时间:2017-08-17 08:51:08

标签: python c arrays

我想向C发送一个double数组来执行python中的优化问题。代码如下:

mathHelper.py

#import sys
#from numpy import *

def addVector(a):
    c = 2*a
    return c 

由于某些原因,取消注释numpy(?)时出错。 C代码如下:

runMe.c

#include </usr/include/python2.7/Python.h>
#include <stdlib.h>
#include <string.h>
#include <numpy/arrayobject.h>

int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue, *pVec;

Py_Initialize();

// this macro is defined by NumPy and must be included
import_array1(-1); 

int nLenslet;
double* h_slopes;
h_slopes = (double *)malloc( nLenslet * sizeof(double));
for (int i = 0; i < nLenslet; i++){
    h_slopes[i] = i;
}
pVec = PyArray_SimpleNewFromData( nLenslet, nLenslet, PyArray_DOUBLE, h_slopes );

// load the python file
PyObject *pval;
PySys_SetPath("/home/roger/Desktop/PythonInC");  // path to the module to import
char *fileID = "mathHelper"; 
pName = PyString_FromString(fileID); 
pModule = PyImport_Import(pName);

char *functionID = "addVector"; 

if (pModule != NULL) {
    pFunc = PyObject_GetAttrString(pModule, functionID);
    if (pFunc && PyCallable_Check(pFunc)) {
        pValue = PyObject_CallFunction(pFunc, pVec);
        if (pValue != NULL) {
            printf("Value returned from the function %s", PyString_AsString(pValue));
        } else {
            PyErr_Print();
        }
    } else {
        if (PyErr_Occurred())
            PyErr_Print();
        fprintf(stderr, "Cannot find function \"%s\"\n", functionID);
    }
}
else {
    PyErr_Print();
    fprintf(stderr, "Failed to load file\n");
    return 1;
}
free(h_slopes);

}

使用

编译
gcc -o final runMe.c -lpython2.7 -std=c99

但是,我收到以下错误消息:

  
    

SystemError:传递给Py_BuildValue的错误格式字符

  

谢谢,

1 个答案:

答案 0 :(得分:0)

我设法通过以下几行取得了一些进展:

#include </usr/include/python2.7/Python.h>
#include <stdlib.h>
#include <string.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>


int main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc, *pValue, *pVec, *pMat, *pParam;
    PyArrayObject *aVec;
    Py_Initialize();    

    import_array1(-1); 


    int n = nLenslet;
    double *h_result, *h_slopes;    
    h_slopes = (double *)malloc( n * sizeof(double));
    h_result = (double *)malloc( n * sizeof(double));

    for (int i = 0; i < n; i++) h_slopes[i] = i; // init

    npy_intp dim[] = {n};
    pVec = PyArray_SimpleNewFromData( 1, dim, NPY_DOUBLE, h_slopes );
    if (pVec == NULL) printf("Cannot fill Python object.\n");

    // load mathHelper.py
    PySys_SetPath("../Python2C");  // path to the module to import
    char *fileID = "mathHelper"; 
    pName = PyString_FromString(fileID); 
    pModule = PyImport_Import(pName);
    char *functionID = "addVector";

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, functionID);
        if (pFunc && PyCallable_Check(pFunc)) {
             pValue = PyObject_CallFunction(pFunc, "O", pVec); 
             PyArray_Descr *dtype = NULL;
             int ndim = 0;
             npy_intp dim2 = {n};
             if (PyArray_GetArrayParamsFromObject(pValue, NULL, 1, &dtype, &ndim, &dim2, &aVec, NULL) != 0) {
                  printf("Failed to convert PyObj to PyArray");
             }
             if (aVec != NULL) {
                 if (PyArray_Check(aVec) == 1) {
                     int m = PyArray_NDIM(aVec);
                     printf("Dimension of array: %i\n",m);
                     h_result = PyArray_GetPtr(aVec, dim);
                     printf("Check results: \n");
                     for (int i = 0; i < 10; i++)
                     {
                         printf("%f\n",h_result[i]);
                     }
                 }  
                 else {
                      printf("Not a Numpy array");
                  }             
            } else {
                  PyErr_Print();
            }
       } else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"\n", functionID);
       }
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load file\n");
        return 1;
    }

    free(h_slopes);
    free(h_mirrorInput);
    free(mat);

    // Finish the Python Interpreter
    Py_Finalize();   

    return 0; 
}

使用与上一篇文章相同的命令行,没有错误也没有警告。 Python命令处理得很好(我通过打印到txt文件来检查它)。 输出屏幕显示:

Dimension of array: 1
Check results: 
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
-nan

显然不正确,因为它应该是[0 2 4 ... 18] 这意味着我仍然无法直接从PyObj或PyArrayObject访问C中的数据。谁能帮我把手放在那里?谢谢,