在嵌入 C++ 后从 Python 中提取值
Extracting value from Python after it's embedded in C++
我有以下嵌入 Python 的缩短程序(为了简短起见,它删除了所有错误处理等)。它创建 Python 函数作为字符串(这是我手头的问题所必需的),然后尝试调用它并使用 __builtin__.eval
.
获取它返回的任何内容
#include <Python.h>
#include <iostream>
int main() {
// Initialize Python
Py_Initialize();
// Import builtin to get an access to eval
PyObject *builtins = PyImport_ImportModule("__builtin__");
PyObject *eval = PyObject_GetAttrString(builtins, "eval");
// Create an argument tuple for the eval
PyObject * args = PyTuple_New(1);
PyObject * name = PyString_FromString("f(10)");
PyTuple_SetItem(args, 0, name);
// Create a function
PyRun_SimpleString("f = lambda x: x * 2 - 3");
// Try to get the result of the function execution by calling eval on it
PyObject * result = PyObject_CallObject(eval, args);
// Fail if the result is null pointer
assert(result != NULL);
// Destroy Python frame
Py_Finalize();
}
换句话说,这个程序类似于下面的 Python 程序:
f = lambda x: x * 2 - 3
import __builtin__
print __builtin__.eval("f(10)")
问题是:它在 Python 中完美运行(返回 17)。但在 C++ 中,PyObject_CallObject
returns NULL 指针和程序在 assert 处失败,即使 eval 显然应该返回 f(10) 的结果。我的问题是为什么?
感谢您的回答!
P.S。如果您想尝试自己编译,请在 Unix 系统上使用以下命令(我在 Ubuntu 上使用它):
g++ -I/usr/include/python2.7 progname.cpp -lpython2.7 -g
实际上我自己已经想出了如何做到这一点。不需要使用 eval()
来提取函数执行的结果。相反,您可以执行以下操作:
#include <Python.h>
#include <iostream>
int main() {
// Initialize Python
Py_Initialize();
// Create a function
PyRun_SimpleString("f = lambda x: x * 2 - 3");
// Import __main__ where the f is stored
PyObject *main = PyImport_ImportModule("__main__");
PyObject *function = PyObject_GetAttrString(main, "__function");
// Create an argument tuple for the function
PyObject * args = PyTuple_New(1);
PyObject * first_argument = PyInt_FromLong(10);
PyTuple_SetItem(args, 0, first_argument);
// Call the function and get its result
PyObject * result = PyObject_CallObject(function, args);
// Output the result
cout << PyInt_AsLong(result) << endl;
// Destroy Python frame
Py_Finalize();
}
但是,我仍然很好奇为什么 eval
没有像我原来的问题那样工作
我有以下嵌入 Python 的缩短程序(为了简短起见,它删除了所有错误处理等)。它创建 Python 函数作为字符串(这是我手头的问题所必需的),然后尝试调用它并使用 __builtin__.eval
.
#include <Python.h>
#include <iostream>
int main() {
// Initialize Python
Py_Initialize();
// Import builtin to get an access to eval
PyObject *builtins = PyImport_ImportModule("__builtin__");
PyObject *eval = PyObject_GetAttrString(builtins, "eval");
// Create an argument tuple for the eval
PyObject * args = PyTuple_New(1);
PyObject * name = PyString_FromString("f(10)");
PyTuple_SetItem(args, 0, name);
// Create a function
PyRun_SimpleString("f = lambda x: x * 2 - 3");
// Try to get the result of the function execution by calling eval on it
PyObject * result = PyObject_CallObject(eval, args);
// Fail if the result is null pointer
assert(result != NULL);
// Destroy Python frame
Py_Finalize();
}
换句话说,这个程序类似于下面的 Python 程序:
f = lambda x: x * 2 - 3
import __builtin__
print __builtin__.eval("f(10)")
问题是:它在 Python 中完美运行(返回 17)。但在 C++ 中,PyObject_CallObject
returns NULL 指针和程序在 assert 处失败,即使 eval 显然应该返回 f(10) 的结果。我的问题是为什么?
感谢您的回答!
P.S。如果您想尝试自己编译,请在 Unix 系统上使用以下命令(我在 Ubuntu 上使用它):
g++ -I/usr/include/python2.7 progname.cpp -lpython2.7 -g
实际上我自己已经想出了如何做到这一点。不需要使用 eval()
来提取函数执行的结果。相反,您可以执行以下操作:
#include <Python.h>
#include <iostream>
int main() {
// Initialize Python
Py_Initialize();
// Create a function
PyRun_SimpleString("f = lambda x: x * 2 - 3");
// Import __main__ where the f is stored
PyObject *main = PyImport_ImportModule("__main__");
PyObject *function = PyObject_GetAttrString(main, "__function");
// Create an argument tuple for the function
PyObject * args = PyTuple_New(1);
PyObject * first_argument = PyInt_FromLong(10);
PyTuple_SetItem(args, 0, first_argument);
// Call the function and get its result
PyObject * result = PyObject_CallObject(function, args);
// Output the result
cout << PyInt_AsLong(result) << endl;
// Destroy Python frame
Py_Finalize();
}
但是,我仍然很好奇为什么 eval
没有像我原来的问题那样工作