2016-01-05 1 views
2

Я работаю с расширением Python-C, в котором файл python переходит в список (массив) в файл C, а файл C возвращает три удвоения. В первый раз, когда я вызываю свой файл тестирования (он импортирует файл c и вызывает функцию c), программа работает нормально. Однако, если я снова вызову тестовый файл, программа зависает и никогда не достигает выполнения. Я не знаю, где эта проблема. Я чувствую, что это связано с тем, что файл c никогда не прекращает выполнение, если это возможно или имеет смысл?Python C Extension + сбой после вызова файла python несколько раз.

Кроме того, я разделяю и освобождаю переменные, так что это не проблема.

Мой C API выглядит следующим образом:

Спасибо любезно.

#include <Python.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "workingHyperbolic.c" 

PyObject* py_fit(PyObject* self, PyObject* args) 
{ 
    PyObject* seqx; 
    PyObject* seqy; 
    double p[3] = {1, 1, 1};   /* Initial conditions */ 
    double *carrayx; 
    double *carrayy; 
    double c, d, a; 
    int seqlen; 
    int i; 

    /* get argument as a sequence */ 
    if(!PyArg_ParseTuple(args, "OO", &seqx, &seqy))     //ParseTuple converts values from Python to C representation. By calling NULL, the appropriate extension is raised 
     return NULL; 
    seqx = PySequence_Fast(seqx, "argument must be iterable"); 
    seqy = PySequence_Fast(seqy, "argument must be iterable"); 
    if(!seqx) 
     return 0; 
    if(!seqy) 
     return 0; 
    /* prepare data as an array of doubles */ 
    seqlen = PySequence_Fast_GET_SIZE(seqx);   // get length of the object, assuming that the seqx is not NULL - faster than Pysequence_Size because seqx is a list or tuple 
    carrayx = malloc(seqlen*sizeof(double));  //Allocates n bytes and returns a pointer of type void* to the allocated memory 
    carrayy = malloc(seqlen*sizeof(double)); 
    if(!carrayx) { 
     Py_DECREF(seqx);        // CPython Garbage Collector uses "Reference Counting" to maintain a list of references to an object. 
                 //If reference count fallst oz ero than garbage collector can deallocate space for that object. 
     return PyErr_NoMemory(); 
    } 
    if(!carrayy) { 
     Py_DECREF(seqy); 
     return PyErr_NoMemory(); 
    } 
    for(i=0; i < seqlen; i++) { 
     PyObject *fitemx; 
     PyObject *fitemy; 
     PyObject *itemx = PySequence_Fast_GET_ITEM(seqx, i);   //Return the sequence seqx as a list, 
     PyObject *itemy = PySequence_Fast_GET_ITEM(seqy, i); 
     if(!itemx) { 
      Py_DECREF(seqx); 
      free(carrayx); 
      return 0; 
     } 
     if(!itemy) { 
      Py_DECREF(seqy); 
      free(carrayy); 
      return 0; 
     } 
     fitemx = PyNumber_Float(itemx);     //Returns the itemx converted to a float object on success, 
     fitemy = PyNumber_Float(itemy); 
     if(!fitemx) { 
      Py_DECREF(seqx); 
      free(carrayx); 
      PyErr_SetString(PyExc_TypeError, "all items must be numbers"); 
      return 0; 
     } 
     if(!fitemy) { 
      Py_DECREF(seqy); 
      free(carrayy); 
      PyErr_SetString(PyExc_TypeError, "all items must be numbers"); 
      return 0; 
     } 
     carrayx[i] = PyFloat_AS_DOUBLE(fitemx);    //Returns the C double value of Python float x, very fast, without error checking. 
     carrayy[i] = PyFloat_AS_DOUBLE(fitemy);    //Returns the C double value of Python float x, very fast, without error checking. 
     PyErr_Occurred(); 
     Py_XDECREF(fitemx); 
     Py_XDECREF(fitemy); 
    } 

    /* clean up, compute, and return result */ 
    Py_DECREF(seqx); 
    Py_DECREF(seqy); 
    c = getParameters(carrayx, carrayy, p, 'c'); 
    d = getParameters(carrayx, carrayy, p, 'd'); 
    a = getParameters(carrayx, carrayy, p, 'a'); 
    printf("\n%lf", c); 
    printf("\n%lf", d); 
    printf("\n%lf", a); 
    free(carrayx); 
    free(carrayy); 
    return Py_BuildValue("ddd", c,d,a);   // creates python objects FROM C data type to return result back to Python. 
} 

// static PyObject *_raise_error(PyObject *py_fit) { 
    // PyErr_SetString(PyExc_ValueError, "Vaue Error"); 
    // PyErr_SetString(PyExc_BaseException, "Base Error"); 
    // PyErr_SetString(PyExc_Exception, "Exception"); 
    // PyErr_SetString(PyExc_ArithmeticError, "Arithmetic"); 
    // PyErr_SetString(PyExc_LookupError, "PyExc_LookupError"); 
    // PyErr_SetString(PyExc_AssertionError, "PyExc_AssertionError"); 
    // PyErr_SetString(PyExc_AttributeError, "PyExc_AttributeError"); 
    // PyErr_SetString(PyExc_BlockingIOError, "PyExc_BlockingIOError"); 
    // PyErr_SetString(PyExc_FloatingPointError, "PyExc_FloatingPointError."); 
    // PyErr_SetString(PyExc_EOFError, "PyExc_EOFError"); 
    // return Py_RETURN_NONE; 
// } 

/* DECLARATION OF METHODS*/ 
PyMethodDef methods[] = { 
    {"fit",(PyCFunction)py_fit, METH_VARARGS, "Descirption"}, 
    {NULL,NULL,0,NULL} 
}; 

// Module Definition Structure 
struct PyModuleDef fittermod = { 
    PyModuleDef_HEAD_INIT,"fit", NULL, -1, methods 
}; 
+0

Если 'carrayy' является' NULL' и 'carrayx', вы не можете терять ресурсы, в расширениях python, которые могут быть очень плохими. –

+0

@iharob: что вы подразумеваете под carrayy, это Null и carrayx нет? – littlebluedeer

+0

Вы повторяете ту же ошибку снова и снова. Я бы переписал всю функцию. Если 'itemx'' 'NULL''' 'free()' 'carrayx', но вы не' free() '' carrayy', также вы вызываете 'PyError_Occurred()', когда он, видимо, был успешным. Также опубликуйте код python, я подозреваю, что вы не передаете последовательность, а список. –

ответ

1

Спасибо всем! Проблема заключалась в том, что в несовместимом параметре (параметре p) выполнялась моя другая c-процедура.