使用C API PyRun_String时的Python SystemError

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用C API PyRun_String时的Python SystemError相关的知识,希望对你有一定的参考价值。

我试图在C ++程序中运行一些python文件,它实际上包含在C ++代码中作为std::string称为command

我成功使用PyRun_SimpleString(command.c_str()),但这可以防止获得异常信息。

我现在尝试以下方式:

PyObject* result = PyRun_String(command.c_str(), Py_file_input, PyEval_GetGlobals(), PyEval_GetLocals());

但是,这会引发:

SystemError: frame does not exist

我究竟做错了什么?

更新:

我尝试使用以下方法将进程拆分为compile + eval:

PyObject* code = Py_CompileString(command.c_str(), filename.c_str(), Py_file_input);
PyObject* result = PyEval_EvalCode(code, PyEval_GetGlobals(), PyEval_GetLocals());

现在,错误是不同的:

SystemError: PyEval_EvalCodeEx: NULL globals

这可能更具说明性,正如它在C API doc中所说的::

返回当前执行帧中全局变量的字典,如果当前没有帧正在执行,则返回NULL。

我不确定我理解框架是什么。

答案

我找到了解决方案。我可能还没有理解帧是否正在执行,但事实证明,在启动解释器之后,没有帧正在运行。这就是为什么PyEval_GetGlobals()PyEval_GetLocals()返回NULL并在以后造成错误。

相反,默认模块__main__的名称空间应该用作全局变量和本地名称空间:

PyObject* d = PyModule_GetDict(PyImport_AddModule("__main__"));
PyObject* result = PyRun_String(command.c_str(), Py_file_input, d, d);
Py_DECREF(result);

以上是关于使用C API PyRun_String时的Python SystemError的主要内容,如果未能解决你的问题,请参考以下文章

传递给第三方 API 时的 C++ const std:string& 安全性

完整性检查时的 sqlite nomem 错误

同时使用 HTTP 和 WebSockets 时的 API 命名约定

在 Laravel 中使用 API 时的处理速率限制

DELPHI调用DLL时的回调函数问题

使用 Gmail API 时的网络流量收费