将python嵌入到C++中无法按预期工作

Embedding python into C++ does not work as expected

本文关键字:工作 python C++      更新时间:2023-10-16

我正在将Python嵌入到C++应用程序中。

当我运行下面的C++代码并返回时间戳时,它运行得很好。

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 : %dn", PyInt_AsLong(pValue)); // I get the correct timestamp
Py_Finalize();

现在我想得到sys.path。但类似的代码给我带来了错误:

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 : %dn", PyInt_AsLong(pValue));
Py_Finalize();

我想问题是time.time()是一个函数调用,而sys.path是一个变量。如果是这样的话:

  1. 如何获得变量的结果
  2. 如何正确地将结果(在本例中为list)转换为C++中有意义的东西,例如字符串数组

如果没有,如何进行?我使用的是Python 2.7.6

谢谢。

您的问题是PyDict_GetItemString(pDict, "path")将返回python列表,并且它是不可调用的。当你执行PyObject_CallObject(pFunc, NULL);时,你就会执行它。这等于sys.path()

这应该有效:

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;

此处为完整代码。