【问题标题】:Embedding python into C++ does not work as expected将 python 嵌入 C++ 不能按预期工作
【发布时间】:2014-09-16 16:08:03
【问题描述】:

我正在将 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 : %d\n", 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 : %d\n", PyInt_AsLong(pValue));

Py_Finalize();

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

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

如果没有,如何进行?我正在使用 Python 2.7.6

谢谢。

【问题讨论】:

  • realmike.org/blog/2012/07/08/embedding-python-tutorial-part-1 你必须这样称呼它:PyObject* sysPath = PySys_GetObject((char*)"path");
  • PyString_AsString(PyDict_GetItemString(pDict, "path")) 工作吗?
  • @Ashalynd 感谢您的链接。如何在 C++ 中将结果作为列表获取? sys.path 返回 list
  • @BradAllred 不,不起作用!
  • 我明白了,是的,当然这是一个字符串列表,而不是单个字符串。我的错。

标签: python c++ python-embedding


【解决方案1】:

您的问题是 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;

完整代码here.

【讨论】:

  • 谢谢,这很完美 :-) 我怀疑类似的线路,但无法进一步调试。
猜你喜欢
  • 1970-01-01
  • 2021-02-26
  • 2013-11-09
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多