首页 > 解决方案 > 在c代码中调用python函数第三次访问冲突写入位置错误

问题描述

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

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”和“不是复数”来找到我需要的“结果”中的值。决赛只有一个。因此,

return result[0]

其次,这里是c代码中的调用过程。首先,“double find_dH”是我在 main 函数中使用的 ac 函数。

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.exe 中 0x00007FEDF8A4E0C(multiarray.cp35-win_amd64.pyd) 处的未处理异常:0xC0000005:访问冲突写入位置 0x000000000000000A。”。但是,“PyEval_CallObject(pv, args)”在第三次之前运行良好。

PyObject* pRet = PyEval_CallObject(pv, args);

我猜这个异常是由以下原因引起的:1.多次导入模块'sympy' 2.每次调用后调用过程中的那些'PyObject'没有空闲。

感谢您的阅读和回答!

标签: pythonc++

解决方案


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

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

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

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;
}

推荐阅读