在 C 代码中调用 Python 函数时第三次出现访问冲突写入位置错误

an access violation writing location error the third time when calling a python function in c code

本文关键字:访问冲突 错误 位置 第三次 代码 调用 函数 Python      更新时间:2023-10-16

我用c编码来解决一个问题。在 c 代码中,我需要调用一个自定义的 python 来求解一个方程。我可以调用 python 函数两次,但是当我第三次调用时,我收到一个错误:"Project.1 中 0x00007FEDF8A4E0C(multiarray.cp35-win_amd64.pyd( 处未处理的异常.exe: 0xC0000005:访问违规写入位置0x000000000000000A。这很奇怪,因为在第一次和第二次,我可以成功调用函数,如果我使用第三次使用的参数独立调用函数,函数可以运行得很好。但是,如果我尝试连续完成工作,则会导致上述异常。我在STACKOVERFLOW中看到过类似的问题">C的Python API:调用python函数2X导致访问冲突写入位置",但是,这个问题没有答案。

PyObject* pRet = PyEval_CallObject(pv, args);

上面的 c 代码是第三次调用 python 函数时导致异常的地方。调用 python 函数的整个过程在下面描述得更清楚。

首先是python函数

from sympy import *
init_printing(use_unicode=True)
def evaluate_dH(eps,bmax,H,B_H1,B_H2):
x=symbols("x")
expr=eps*(x-bmax)**2*x**(H+2)-(H+2)*x*B_H1+(H+1)*B_H2
result=solve(expr,x)#result is a list type

在求解方程时,我使用了">bmax"和"not a complex"两个条件来找到我需要的">结果"中的值。 决赛只有一个。因此

return result[0]

其次,这是 C 代码中的调用过程。 首先,"双find_dH"是我在主函数中使用的c函数。

double find_dH
(....)
{
double B_H2 = findBH(region, vecp_vertex, H + 2, index);
double B_H1 = findBH(region, vecp_vertex, H + 1, index);
double eps = 0.01;
double bmax = findbmax(region, vecp_vertex);
Py_Initialize();
PyObject *pModule = NULL;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
pModule = PyImport_ImportModule("evaluate_dH");
PyObject* pv = PyObject_GetAttrString(pModule, "evaluate_dH");
PyObject* args = PyTuple_New(5);
PyTuple_SetItem(args, 0, Py_BuildValue("d", double(eps)));
PyTuple_SetItem(args, 1, Py_BuildValue("d", double(bmax)));
PyTuple_SetItem(args, 2, Py_BuildValue("i", H));
PyTuple_SetItem(args, 3, Py_BuildValue("d", double(B_H1)));
PyTuple_SetItem(args, 4, Py_BuildValue("d", double(B_H2)));
PyObject* pRet = PyEval_CallObject(pv, args);
double result = PyFloat_AsDouble(pRet);
Py_Finalize();
return result;
}

下面是导致异常的地方:">Project.1 中 0x00007FEDF8A4E0C(multiarray.cp35-win_amd64.pyd( 处的未处理异常.exe:0xC0000005:访问冲突写入位置 0x000000000000000A."。但是,"PyEval_CallObject(pv,args("在第三次之前效果很好。

PyObject* pRet = PyEval_CallObject(pv, args);

我想异常是由以下原因引起的: 1. 多次导入模块"符号" 2. 每次调用后,调用过程中的"PyObject"都没有免费。

感谢您的阅读和回答!

在C++工作时,我在调用时遇到类似的错误

PyObject* pValue = Py_BuildValue("(s)", param);

为了解决这个问题,我将字符串复制到字符*

PyObject* getPythonValueString(string param)
{
char* paramVal = new char[param.length() + 1];
strcpy(paramVal, param.c_str());

PyObject* pValue = Py_BuildValue("(s)", paramVal);
PyErr_Print();
// Remember to clean up.
delete[] paramVal;
return pValue;
}