python - 在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'没有空闲。
感谢您的阅读和回答!
解决方案
在 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;
}
推荐阅读
- angular - 无法从 Angular 5 中的构造函数获取上一个 url
- directx - 如何使用 Direct3D11 阻塞等待计算着色器?
- ios - 更改 datePicker 线条和字体颜色
- r - R group_by %>% full_join 丢失 NA 记录
- python - 有没有办法只用 tensorflow.estimator.train_and_evaluate() 保存最佳模型?
- dart - 我无法理解此 Dart 代码中的 @required 注释
- php - 找不到php输出目录
- mysql - Google App Maker - 从外部 MySql 数据库中引用多个表
- java - Liquibase.properties 读取环境变量
- c# - devDept Eyeshot - ViewportLayout/Viewport 仅在应用程序启动时显示黑屏