【问题标题】:Python C Extension: PyEval_GetLocals() returns NULLPython C 扩展:PyEval_GetLocals() 返回 NULL
【发布时间】:2017-02-24 01:44:51
【问题描述】:

我需要在 C/C++ 中从 Python 读取局部变量。当我尝试PyEval_GetLocals 时,我得到一个 NULL。尽管 Python 已初始化,但仍会发生这种情况。下面是一个最小的例子。

#include <iostream>
#include <Python.h>

Py_Initialize();
PyRun_SimpleString("a=5");
PyObject *locals = PyEval_GetLocals();
std::cout<<locals<<std::endl; //prints NULL (prints 0)
Py_Finalize();

the manual 中,它说如果没有框架正在运行,它会返回 NULL,但是......有一个框架正在运行!

我做错了什么?

我在 Debian Jessie 中运行它。

【问题讨论】:

  • @martineau 但即使是全局变量也返回 NULL!这是否意味着这不是获取变量的适当方法?因为我已经接受了这个答案。 stackoverflow.com/questions/40041498/…
  • @martineau 验证PyRun_SimpleString() 是否正常工作非常容易。我可以打印东西并分配东西,它可以工作。您会建议修复该示例代码吗?
  • @martineau 这也返回 NULL。我在第一次回复你时提到了这一点:-)
  • @martineau 使用您提供的命令打印a 工作并打印5。同样使用print(locals()) 打印locals() 会打印一个包含adict
  • @martineau :( ...

标签: python c++ c python-c-extension python-extensions


【解决方案1】:

原来在范围内访问变量的正确方法是:

Py_Initialize();
PyObject *main = PyImport_AddModule("__main__");
PyObject *globals = PyModule_GetDict(main);
PyObject *a = PyDict_GetItemString(globals, "a");
std::cout<<globals<<std::endl; //Not NULL
Py_Finalize();

【讨论】:

  • 旁注:这会泄漏参考;程序将在退出时清理,但如果您需要调试参考泄漏,这将是另一个需要解决的泄漏。最简单的解决方法是将PyDict_GetItem(globals, PyUnicode_FromString("a")); 更改为PyDict_GetItemString(globals, "a");,这在逻辑上是相同的,除了它为您管理创建和释放PyUnicode 对象,确保它正确DECREF-ed。
  • @ShadowRanger 非常感谢!这是一个重要的注意事项,我相应地更新了我的代码:) 我希望那里不再有泄漏。
  • 请更新您的答案,使其与您的问题基本相同。此外,PyModule_GetDict(main) 似乎会导致编译错误,因为 main 未定义。
  • @martineau 你确定main 是未定义的吗?
  • @martineau 答案中的代码替换了问题中的代码。目的是从 Python 框架中提取一个变量。
猜你喜欢
  • 2016-07-14
  • 1970-01-01
  • 2014-04-12
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 2020-08-10
  • 1970-01-01
相关资源
最近更新 更多