在C中读取Python的全局变量

2 投票
2 回答
2902 浏览
提问于 2025-04-18 13:13

我正在学习如何正确使用Python/C API。其实我只需要读取一个全局变量(在我的例子中是字典,但我先从一个简单的整数变量开始)。

我参考了这个讨论:如何从C语言访问Python全局变量?,以及那里的答案来源:http://bytes.com/topic/python/answers/705918-c-api-embedded-python-how-get-set-named-variables,然后写了这个小程序:

Python代码(tryStuff.py):

var1 = 1

var2 = ['bla', 'blalba']

var3 = {"3" : "Three", "2" : "Two", "1" : "One", "0" : "Ignition!"}

print "end of file - tryStuff!!"

C代码(embedPythonTry.c):

#include <python2.7/Python.h>

int main(int argc, char **argv){
  Py_Initialize();
  PyRun_SimpleString("import sys");
  PyRun_SimpleString("sys.path.append('<the absolute path of the folder in which the python file is located>')");
  PyImport_ImportModule("tryStuff");
  printf("After the import, before the addition\n");
  PyObject *mainModule = PyImport_AddModule("__main__");
  PyObject *var1Py = PyObject_GetAttrString(mainModule, "var1");
  int var1Int = PyInt_AsLong(var1Py);
  printf("var1=%d ; var1==NULL: %d\n", var1Int, var1Py==NULL);
  Py_XDECREF(var1Py);
  Py_Finalize();
  return 0;
}

运行这个C程序的输出是:

end of file - tryStuff!!
After the import, before the addition
var1=-1 ; var1==NULL: 1

这意味着Python解释器找到了并运行了正确的Python脚本,但不知为何它无法读取变量(var1)。

有没有人能发现问题所在?我有点迷茫了。这看起来是应用Python/C API的最简单情况,但它却不工作。我缺少了什么呢?

2 个回答

1

我知道这个问题是很久以前的,但我想把它分享给那些在网上搜索时碰到这个问题的人。

提问者说他的代码不管用,但讽刺的是,我的代码运行得比其他例子还要好。(谢谢你,@et_l)

所以,答案是——如何从C语言访问Python变量——针对提问者的代码(包括提问者写的主模块代码);

#include <stdio.h>
#include <Python.h>

int main () {
  Py_Initialize();
  PyRun_SimpleString("var1 = 1");
  PyRun_SimpleString("var2 = ['bla', 'blalba']");
  PyRun_SimpleString("var3 = {'3' : 'Three', '2' : 'Two', '1' : 'One', '0' : 'Ignition!'}");
  PyRun_SimpleString("print('end of file - tryStuff!!')");

  PyObject *mainModule = PyImport_AddModule("__main__");
  PyObject *var1Py = PyObject_GetAttrString(mainModule, "var1");
  int c_var1 = PyLong_AsLong(var1Py);
  printf("var1 with C: %d\n", c_var1);

  Py_Finalize();
  return 0;
}
1

你应该在调用 PyImport_ImportModule 的结果上使用 PyObject_GetAttrString。我不明白你为什么认为 __main__ 模块应该定义那个变量:

PyObject *mod = PyImport_ImportModule("tryStuff");
PyObject *var1Py = PyObject_GetAttrString(mod, "var1");

你还应该检查一下结果,因为当导入失败时,PyImport_ImportModule 可能会返回 NULL

撰写回答