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

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调用的函数的返回值,或者

现在的问题是: “MyFunc”执行良好,我可以看到“result”的打印。 我不能做的是从C++代码中读取“结果”。extract命令在任何命名空间中都找不到“result”。
我尝试将“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;
}
一些要点:

  • 我将“exec”改为“exec\u file”,从 方便,它还可以与 普通的“exec”
  • 它失败的主要原因是i 未将“本地”名称\u sapce传递给 “exec”或“exec\u文件”-现在是 通过两次传递name_空格进行修复
  • 如果python函数返回 unicode字符串,它们不是 可转换为'std::string',因此我 必须为所有python字符串添加后缀 使用“.encode('ASCII','ignore')”

  • 无论MyFunc返回什么,我都会得到:TypeError:“NoneType”对象不支持项分配比我的更全面的答案,来自(我想)一位家长:)nosklo,我建议您使用PyRun_字符串示例扩展您的答案;它允许更大的灵活性应该通过1而不是0。我似乎不能让我的C++代码找到Python脚本。我在同一个文件夹中有C++应用程序的脚本。pModule总是空的。我在这里做错了什么: