2

I am trying to learn how to use the Python/C API correctly - all I actually need to do is to read a global variable (in my case dictionary - but I'm starting with a simple integer variable). Using the discussion: How to access a Python global variable from C? and the source of the answer there: http://bytes.com/topic/python/answers/705918-c-api-embedded-python-how-get-set-named-variables I wrote this little thing:

Python code (tryStuff.py):

var1 = 1

var2 = ['bla', 'blalba']

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

print "end of file - tryStuff!!"

C code (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;
}

The output of running this c program is:

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

Which means the Python interpreter finds and runs the correct Python script, but somehow it can't manage to read the variable (var1).

Can anyone spot the problem - I am kinda' lost already. It looks like the most simple situation that can be to apply the Python/C API, but it doesn't work. What am I missing?

Community
  • 1
  • 1
et_l
  • 1,868
  • 17
  • 29

2 Answers2

1

You should call PyObject_GetAttrString on the result of PyImport_ImportModule. I have no idea why you think that the __main__ module should define that variable:

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

You should also add the check on the results, since PyImport_ImportModule can return NULL when the import fails.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • 1
    Thanks! I am aware of the need for results-checks, but wanted to get things started first. As for my confusion - I followed the example in the discussion linked above, and the fact that the documentation mentions the __main__ module as the global environment of the running interpreter. Somehow I didn't notice that the PyImport_ImportModule function returns a value (in the example they ignored this value and I actually tried to understand how I should get a hold of the module object). – et_l Jul 14 '14 at 09:24
1

I know this question is from long ago, but this is for others who stumble across this while googling.

OP says his code doesn't work, but ironically, his code worked for me better than other examples.(Thanks, @et_l)

So, the answer - how to access python variables from C - for the OP's code (with the main module code OP wrote);

#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
    Thanks for the comment! @Bakuriu's answer is in fact the correct one __for my question__. Note that in your code you're: 1) initializing python's interpreter 2) defining variables using the c file's `PyRun_SimpleString`, aka defining them in the main module (where you are when you start up the interpreter) 3) fetching the variables from the main module, which makes sense __in your situation__. But in my original question the variables were defined in a python module which I imported using the c file's `PyImport_ImportModule` method. So the variables didn't belong to the main module. – et_l Oct 05 '20 at 09:16