2

I am embedding Python into a C++ application.

When I run the following piece of C++ code, which returns me the timestamp, it works fine.

Py_Initialize(); 
std::string strModule = "time"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
pFunc = PyDict_GetItemString(pDict, "time"); // get the function we want to call
// Call the function and get the return in the pValue
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue == NULL){
 printf('Something is wrong !');
 return 0;
}
printf("Return of python call : %d\n", PyInt_AsLong(pValue)); // I get the correct timestamp
Py_Finalize();

Now I want to get the sys.path. But the similar code throws me error:

Py_Initialize(); 
std::string strModule = "sys"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
pFunc = PyDict_GetItemString(pDict, "path"); // get the function we want to call
// Call the function and get the return in the pValue
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue == NULL){
 printf('Something is wrong !'); // I end up here, why pValue is NULL?
 return 0;
}
printf("Return of python call : %d\n", PyInt_AsLong(pValue));
Py_Finalize();

I guess the problem is that time.time() is a function call whereas sys.path is a variable. If that is the case:

  1. How to get the result of a variable?
  2. How to properly translate the result (in this case a list) to something meaningful in C++ for e.g. an array of strings?

If not, how to proceed? I am using Python 2.7.6

Thanks.

asked Sep 16, 2014 at 16:08
5
  • realmike.org/blog/2012/07/08/embedding-python-tutorial-part-1 you have to call it like that: PyObject* sysPath = PySys_GetObject((char*)"path"); Commented Sep 16, 2014 at 16:16
  • does PyString_AsString(PyDict_GetItemString(pDict, "path")) work? Commented Sep 16, 2014 at 16:19
  • @Ashalynd thanks for the link. How to get the result as a list in C++? sys.path returns a list. Commented Sep 16, 2014 at 16:30
  • @BradAllred No, doesn't work! Commented Sep 16, 2014 at 16:30
  • I see, yes of course that is a list of strings not a single string. my bad. Commented Sep 16, 2014 at 16:32

1 Answer 1

4

Your problem is that PyDict_GetItemString(pDict, "path") will return python list and it is not callable. And when you execute PyObject_CallObject(pFunc, NULL); you will execute it. This is equal to sys.path().

This should work:

PyObject *pName, *pModule, *pDict, *list, *pValue, *item;
int n, i;
char *name;
Py_Initialize(); 
std::string strModule = "sys"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
list = PyDict_GetItemString(pDict, "path"); // get python list
n = PyList_Size(list);
if (n < 0)
 return -1; /* Not a list */
for (i = 0; i < n; i++) { // iterate over list
 item = PyList_GetItem(list, i); /* Can't fail */
 if (!PyString_Check(item)) continue; /* Skip non-string */
 name = PyString_AsString(item);
 std::puts(name);
}
Py_Finalize();
return 0;

Full code here.

answered Sep 16, 2014 at 16:35
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this works perfectly :-) I was suspecting on the similar lines but unable to debug further.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.