CPP中嵌入的Python:如何将数据返回到CPP 当我在C++项目上工作时,我在寻找一个不是我的核心业务的第三方库。我发现了一个非常好的库,它做的正是需要的,但它是用Python编写的。我决定用C++中的Python代码进行实验,使用Boosi.python库。 C++代码看起来像这样: #include <string> #include <iostream> #include <boost/python.hpp> using namespace boost::python; int main(int, char **) { Py_Initialize(); try { object module((handle<>(borrowed(PyImport_AddModule("__main__"))))); object name_space = module.attr("__dict__"); object ignored = exec("from myModule import MyFunc\n" "MyFunc(\"some_arg\")\n", name_space); std::string res = extract<std::string>(name_space["result"]); } catch (error_already_set) { PyErr_Print(); } Py_Finalize(); return 0; } import thirdparty def MyFunc(some_arg): result = thirdparty.go() print result import thirdparty def MyFunc(some_arg): result = thirdparty.go() return result
现在的问题是: “MyFunc”执行良好,我可以看到“result”的打印。 我不能做的是从C++代码中读取“结果”。extract命令在任何命名空间中都找不到“result”。CPP中嵌入的Python:如何将数据返回到CPP 当我在C++项目上工作时,我在寻找一个不是我的核心业务的第三方库。我发现了一个非常好的库,它做的正是需要的,但它是用Python编写的。我决定用C++中的Python代码进行实验,使用Boosi.python库。 C++代码看起来像这样: #include <string> #include <iostream> #include <boost/python.hpp> using namespace boost::python; int main(int, char **) { Py_Initialize(); try { object module((handle<>(borrowed(PyImport_AddModule("__main__"))))); object name_space = module.attr("__dict__"); object ignored = exec("from myModule import MyFunc\n" "MyFunc(\"some_arg\")\n", name_space); std::string res = extract<std::string>(name_space["result"]); } catch (error_already_set) { PyErr_Print(); } Py_Finalize(); return 0; } import thirdparty def MyFunc(some_arg): result = thirdparty.go() print result import thirdparty def MyFunc(some_arg): result = thirdparty.go() return result,c++,python,boost-python,C++,Python,Boost Python,现在的问题是: “MyFunc”执行良好,我可以看到“result”的打印。 我不能做的是从C++代码中读取“结果”。extract命令在任何命名空间中都找不到“result”。 我尝试将“result”定义为全局变量,甚至尝试返回一个元组,但我无法让它正常工作。您应该能够从MyFunc返回结果,结果会出现在您当前调用的变量“ignored”中。这消除了以任何其他方式访问它的需要。我认为您需要的是PyObject\u CallObject(,),它返回作为PyObject调用的函数的返回值,或者
我尝试将“result”定义为全局变量,甚至尝试返回一个元组,但我无法让它正常工作。您应该能够从MyFunc返回结果,结果会出现在您当前调用的变量“ignored”中。这消除了以任何其他方式访问它的需要。我认为您需要的是
PyObject\u CallObject(,)
,它返回作为PyObject调用的函数的返回值,或者PyRun\u字符串(,Py\u eval\u input,)
,它计算单个表达式并返回其结果。首先,将函数更改为返回值<代码>打印ing它会使事情复杂化,因为您希望收回值。假设您的MyModule.py
如下所示:
#include <string>
#include <iostream>
#include <boost/python.hpp>
using namespace boost::python;
int main(int, char **)
{
Py_Initialize();
try
{
object module((handle<>(borrowed(PyImport_AddModule("__main__")))));
object name_space = module.attr("__dict__");
object ignored = exec("from myModule import MyFunc\n"
"MyFunc(\"some_arg\")\n",
name_space);
std::string res = extract<std::string>(name_space["result"]);
}
catch (error_already_set)
{
PyErr_Print();
}
Py_Finalize();
return 0;
}
import thirdparty
def MyFunc(some_arg):
result = thirdparty.go()
print result
import thirdparty
def MyFunc(some_arg):
result = thirdparty.go()
return result
现在,要想做你想做的事情,你必须超越基本的嵌入,就像。以下是运行函数的完整代码:
#include <Python.h>
int
main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pArg, *pResult;
int i;
Py_Initialize();
pName = PyString_FromString("MyModule.py");
/* Error checking of pName left out as exercise */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "MyFunc");
/* pFunc is a new reference */
if (pFunc) {
pArgs = PyTuple_New(0);
pArg = PyString_FromString("some parameter")
/* pArg reference stolen here: */
PyTuple_SetItem(pArgs, 0, pArg);
pResult = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pResult != NULL) {
printf("Result of call: %s\n", PyString_AsString(pResult));
Py_DECREF(pResult);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load module");
return 1;
}
Py_Finalize();
return 0;
}
#包括
int
main(int argc,char*argv[])
{
PyObject*pName、*pModule、*pFunc;
PyObject*pArgs,*pArg,*pResult;
int i;
Py_初始化();
pName=PyString_FromString(“MyModule.py”);
/*检查作为练习遗漏的pName时出错*/
pModule=PyImport\u Import(pName);
Py_DECREF(pName);
if(pModule!=NULL){
pFunc=PyObject_GetAttrString(pModule,“MyFunc”);
/*pFunc是一个新的参考*/
如果(pFunc){
pArgs=PyTuple_New(0);
pArg=PyString\u FromString(“某个参数”)
/*此处的pArg参考:*/
PyTuple_SetItem(pArgs,0,pArg);
PRESLT=PyObject_CallObject(pFunc,pArgs);
Py_DECREF(pArgs);
如果(预设值!=NULL){
printf(“调用结果:%s\n”,PyString_AsString(pResult));
Py_DECREF(预设值);
}
否则{
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,“调用失败\n”);
返回1;
}
}
否则{
如果(Pyrr_发生())
PyErr_Print();
fprintf(stderr,“找不到函数”);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
否则{
PyErr_Print();
fprintf(stderr,“加载模块失败”);
返回1;
}
Py_Finalize();
返回0;
}
基于TthiΖΖΖΖΖΖΥ、Josh和Nosklo的答案,我最终使用boost.python实现了它:
Python:
import thirdparty
def MyFunc(some_arg):
result = thirdparty.go()
return result
C++:
#包括
#包括
#包括
使用名称空间boost::python;
int main(int,char**)
{
Py_初始化();
尝试
{
对象模块=导入(“\uuuu main\uuuu”);
对象名\u space=module.attr(“\uu dict\uuu”);
exec_文件(“MyModule.py”、名称空间、名称空间);
对象MyFunc=名称空间[“MyFunc”];
对象结果=MyFunc(“某些参数”);
//结果是一本字典
std::string val=extract(结果[“val”]);
}
捕获(已设置错误)
{
PyErr_Print();
}
Py_Finalize();
返回0;
}
一些要点:
无论MyFunc返回什么,我都会得到:TypeError:“NoneType”对象不支持项分配比我的更全面的答案,来自(我想)一位家长:)nosklo,我建议您使用PyRun_字符串示例扩展您的答案;它允许更大的灵活性代码>应该通过1而不是0。我似乎不能让我的C++代码找到Python脚本。我在同一个文件夹中有C++应用程序的脚本。pModule总是空的。我在这里做错了什么: