C++嵌入Python踩坑日记

文章讨论了C++嵌入Python脚本时,如何避免Py_Finalize()导致的不干净问题和内存泄漏。提出不使用释放函数并检查初始化次数的方法,确保在Python3.4版本中的稳定调用。还涉及了Python库的打包和发布注意事项。
摘要由CSDN通过智能技术生成

一、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中所需的头文件。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值