一、C++多次嵌入调用py脚本时间,释放不干净的问题
解决方法:不使用Py_Finalize()、Py_DECREF等一系列释放函数,即可重复调用。
这个地方我也大为不解,官方给的例程可能在Py_DECREF()后存在阻塞等问题,在删除了释放函数之后,即可用外部接口重复调用。本人代码嵌入调用跑了100000次(用时10h)后,在任务管理器中无内存泄漏,也不清楚这个释放函数的具体意义,如要深究可能得看源码。参考博客:记QT混编c++多次调用python脚本所出现的问题_py_initialize();第二次调用报错-CSDN博客
二、Py_initialize只能初始化一次,同时使用Py_Finalize()释放后第二次Py_initialize报错
MPF_U32 mpf_plot_py_init(MPF_ERROR_INFO* pstErr) {
if (s_u32Count == MPF_FALSE && !Py_IsInitialized())
{
if (s_u32Count) { // error handling
Py_InitializeEx(s_u32Count);
return MPF_OK;
}
// python Interpreter Initialize
// Py_SetPythonHome((wchar_t*)(L"../../../../ExtLib/Py_Env/pyddll")); // python explainer position
Py_Initialize();
if (!Py_IsInitialized()) { // error handling
sprintf_s(pstErr->acRuntime, sizeof(pstErr->acRuntime), "Python Initialize Error!");
pstErr->u32Code = MPF_PLOT_ERR_PY_INITIALIZE;
return MPF_ERR;
}
else {
s_u32Count = MPF_TRUE;
// Set the py file path
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('../../../../PyPrj/src')");
// get numpy datatype
_import_array();
return MPF_OK;
}
}
return MPF_ERR;
}
通过使用static s_u32Count来判断是否初始化过一次,如果初始化过后,那么下一次不再初始化,如此来规避多次初始化导致的问题。
同时不再在末尾添加Py_Finalize(),防止多次释放问题。这里不使用Py_Finalize()也不会导致内存泄漏,如上面所诉,循环调用运行了10h后程序仍然健壮。
三、本文使用的Python版本为3.4,其他版本可能有更新,以上错误仅针对3.4这个版本
在封装成包发布出去的时候,需要将pyd以及dll,以及所写的py文件,或者将py文件转换成pyd文件一起发布到Debug或者Release中,同时将Python自带的Lib库打包到Debug和Release同一路径下,include内是所封装的库所用cpp中所需的头文件。