Я работаю с расширением 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
};
Если 'carrayy' является' NULL' и 'carrayx', вы не можете терять ресурсы, в расширениях python, которые могут быть очень плохими. –
@iharob: что вы подразумеваете под carrayy, это Null и carrayx нет? – littlebluedeer
Вы повторяете ту же ошибку снова и снова. Я бы переписал всю функцию. Если 'itemx'' 'NULL''' 'free()' 'carrayx', но вы не' free() '' carrayy', также вы вызываете 'PyError_Occurred()', когда он, видимо, был успешным. Также опубликуйте код python, я подозреваю, что вы не передаете последовательность, а список. –