pythoncextension+;多次调用python文件后崩溃。
我一直在使用一个Python-C扩展,其中Python文件以列表(数组)的形式传递给C文件,C文件返回三个double。 第一次调用测试文件(它导入c文件并调用c函数)时,程序工作正常。但是,如果我再次调用测试文件,程序将冻结,永远无法执行。 我不知道问题发生在哪里。我有一种感觉,这与c文件永不停止执行有关,如果可能或有意义的话 此外,我正在对变量进行mallocing和free,所以这不是一个问题 我的C API如下所示: 谢谢你pythoncextension+;多次调用python文件后崩溃。,python,c,extension-methods,Python,C,Extension Methods,我一直在使用一个Python-C扩展,其中Python文件以列表(数组)的形式传递给C文件,C文件返回三个double。 第一次调用测试文件(它导入c文件并调用c函数)时,程序工作正常。但是,如果我再次调用测试文件,程序将冻结,永远无法执行。 我不知道问题发生在哪里。我有一种感觉,这与c文件永不停止执行有关,如果可能或有意义的话 此外,我正在对变量进行mallocing和free,所以这不是一个问题 我的C API如下所示: 谢谢你 #include <Python.h> #incl
#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
};
#包括
#包括
#包括
#包括“working.c”
PyObject*py_-fit(PyObject*self,PyObject*args)
{
PyObject*seqx;
PyObject*seqy;
双p[3]={1,1,1};/*初始条件*/
双倍*carrayx;
双*卡雷伊;
双c,d,a;
内特赛克伦;
int i;
/*将参数作为序列获取*/
如果(!PyArg_ParseTuple(args,“OO”,&seqx,&seqy))//ParseTuple将值从Python转换为C表示形式。通过调用NULL,将引发相应的扩展
返回NULL;
seqx=PySequence_Fast(seqx,“参数必须是可写的”);
seqy=PySequence_Fast(seqy,“参数必须是可写的”);
如果(!seqx)
返回0;
如果(!sexy)
返回0;
/*以双精度数组的形式准备数据*/
seqlen=PySequence_Fast_GET_SIZE(seqx);//获取对象的长度,假设seqx不是NULL-比PySequence_SIZE快,因为seqx是列表或元组
carrayx=malloc(seqlen*sizeof(double));//分配n个字节并返回void*类型的指针到分配的内存
carrayy=malloc(seqlen*sizeof(双));
如果(!carrayx){
Py_DECREF(seqx);//CPython垃圾收集器使用“引用计数”来维护对对象的引用列表。
//如果引用计数下降,则垃圾收集器可以为该对象释放空间。
返回PyErr_nomery();
}
如果(!carrayy){
Py_DECREF(seqy);
返回PyErr_nomery();
}
对于(i=0;i谢谢大家!问题是传递一个与我的另一个c例程不兼容的参数(参数p) 如果carrayy
为NULL
而carrayx
为空,则在python扩展中可能会泄漏资源,这可能非常糟糕。@iharob:你说carrayy为NULL而carrayx不为空是什么意思?你一再犯同样的错误。我会重写整个函数。如果itemx
为NULL
您可以free()
carrayx
但是您没有free()
carrayy
,那么当它显然已经成功时,您也可以调用PyError\u occurrent()
。同时发布python代码,我怀疑您传递的不是序列,而是列表。@iharob:谢谢,但我不太明白。我想如果我检查一个是