封装一个python资源锁类,在调用python api时调用
class PyThreadStateLock {
public:
PyThreadStateLock() {
state = PyGILState_Ensure();
}
~PyThreadStateLock() {
PyGILState_Release(state);
}
public:
PyGILState_STATE state;
};
主线程中完成初始化
// 搜索目录设定
Py_SetPythonHome(PathHelper::StdApplicationFile(L"plugin").c_str());
// 初始化
Py_Initialize();
if (!Py_IsInitialized())
{
LOG_EX("python初始化失败");
return -1;
}
// 初始化线程支持
PyEval_InitThreads();
// 启动子线程前执行 为了释放PyEval_InitThreads获取的全局锁,否则子线程可能无法获取到全局锁
PyEval_ReleaseThread(PyThreadState_Get());
// 启动线程执行python代码
.......
// 保证子线程调用都结束释放资源
PyGILState_Ensure();
Py_Finalize();
python封装代码
template<typename... Args>
inline int call_python_func(std::string module_name, std::string func_name,std::string & func_result,std::string args_type, Args... args) {
PyThreadStateLock PyThreadLock;
PyObject* ptype, * pvalue, * ptraceback;
LOG_EX("Py_GetPythonHome %ws", Py_GetPythonHome());
LOG_EX("Py_GetProgramFullPath %ws", Py_GetProgramFullPath());
LOG_EX("Py_GetPath %ws", Py_GetPath());
LOG_EX("Py_GetPrefix %ws", Py_GetPrefix());
LOG_EX("Py_GetExecPrefix %ws", Py_GetExecPrefix());
LOG_EX("Py_GetExecPrefix %ws", Py_GetExecPrefix());
PyObject* pModule = NULL;//声明变量
PyObject* pFunc = NULL;// 声明变量
pModule = PyImport_ImportModule(module_name.c_str());//这里是要调用的文件名
if (pModule == NULL)
{
LOG_EX("py模块加载失败:%s",module_name.c_str());
//PyErr_Fetch(&ptype, &pvalue, &ptraceback);
// // 检查异常类型
//PyObject* ptype_str = PyObject_Str(ptype);
//const char* type_str = PyUnicode_AsUTF8(ptype_str);
//LOG_EX("Exception type: %s\n", type_str);
//Py_XDECREF(ptype_str); // 释放对象引用
//// 获取异常值
//PyObject* pvalue_str = PyObject_Str(pvalue);
//const char* value_str = PyUnicode_AsUTF8(pvalue_str);
//LOG_EX("Exception value: %s\n", value_str);
//Py_XDECREF(pvalue_str); // 释放对象引用
//// 清除异常信息
//PyErr_Clear();
goto pyfunc_end;
}
else {
pFunc = PyObject_GetAttrString(pModule, func_name.c_str());
//给python函数参数赋值
PyObject* pArgs = NULL;
if (args_type != "") {
pArgs = Py_BuildValue(args_type.c_str(), args...);
}
//调用函数
PyObject* pRet = PyObject_CallObject(pFunc, pArgs);
char *res = nullptr;
//转换返回类型
PyArg_Parse(pRet, "s", &res);
if (res) {
func_result = res;
}
else {
LOG_EX("python方法调用失败");
}
Py_DecRef(pRet);
Py_DecRef(pArgs);
Py_DecRef(pFunc);
}
pyfunc_end:
return 0;
}
调用示例
// 调用python_module中的Main函数 参数类型为sss(三个字符串类型),返回值为std::string 存储到js_doc中
call_python_func(“python_module”, "Main", js_doc, "sss", “1”, “2”, “3”);
评论区