在C++中嵌入Python - 从C++程序运行Python

ale*_*pov 2 c++ python embed

谢谢你们快速回复:)我想我理解你的建议,但这不是我需要的.说实话,我不知道什么是正确的技术来做我需要的.

我有一个程序,在它运行期间有时需要调用python来执行某些任务.我需要一个调用python并捕获pythons stdout的函数

          pythonCallBackFunc(const char* pythonInput)
Run Code Online (Sandbox Code Playgroud)

此功能是执行此操作的功能.

例如:

     pythonCallBackFunc("5**2") needs to print on stdin(or some other file): 
     PythonResult: 25
     pythonCallBackFunc("print 5**2") needs to print on stdin(or some other file): 
     PythonResult: 25
     pythonCallBackFunc("'a'+'b'") needs to print on stdin(or some other file):
     PythonResult: 'ab' 
     pythonCallBackFunc("print 'a'+'b'") needs to print on stdin(or some other file):
     PythonResult: ab 
     pythonCallBackFunc("execfile('temp.py')")
     it should print nothing but is needs to run the temp.py script

     the next 2 calls need to print the value of result, meaning 4.
     pythonCallBackFunc("result = 4")
     pythonCallBackFunc("print result")
Run Code Online (Sandbox Code Playgroud)

我的问题是捕获给定命令(pythonInput)的所有python输出.我尝试过的第一件事是使用这个脚本将python的sdtout和stderr重定向到一个文件:

    #stdout.py
    import sys
    saveout = sys.stdout                                     
    fsock = open('out.log', 'w')                           
    sys.stdout = fsock                                      

    #stdout_close.py
    sys.stdout = saveout                                    
    fsock.close()        

    #stdout_close.py
    fsock = open('error.log', 'w')         
    sys.stderr = fsock  
Run Code Online (Sandbox Code Playgroud)

在重定向之后,我使用了函数Py_run_SimpleString

没关系但是这个函数忽略了这些类型的命令:

    Py_run_SimpleString("'a'+'b'")
Run Code Online (Sandbox Code Playgroud)

输出是空的....

亚历克斯

spa*_*ist 5

您使用的示例代码仅在Python代码返回可由C++类型表示的对象时才起作用int.此行为是由您的代码行引起的:

int boostOutputStr = extract<int>(result);
Run Code Online (Sandbox Code Playgroud)

您必须处理的一般问题是C++是一种严格类型的语言,而Python则不是.python语句(或python函数调用)可以返回任何类型的对象,并且对函数的一次调用可以返回与下一次调用同一函数不同类型的对象.在C++中,必须很好地定义函数的返回类型(以及参数的类型).但是,C++为您希望更灵活的情况提供模板.通过定义一个模板函数(以及boost :: python的提取函数是一个很好的例子),您可以将该函数用于不同的类型配置.但是,您的模板函数代码将由编译器为您使用它的每种类型实例化.即 模板方法只会让您省去复制和粘贴的繁琐工作,然后修改您使用它的所有类型的代码.编译器会这样做,因为你知道.但是在编译时必须很好地定义所有类型.有时你不能让函数返回int有时string取决于用户输入.这就是Python或其他高级语言等脚本语言的优点.在C++中,必须在编译代码时设置所有类型.

那么在你的情况下该怎么办?

您可以直接pythonCallBackFunc返回result,而不必将其转换为int.所以返回值是类型object(来自boost :: python)并且代表一个Python对象.您可以将其转换extract<>为代码中稍后需要的任何类型.(我假设您确实希望Python表达式的返回值传递回代码,而不是一直打印出来cout.)

或者,您也可以使您的函数pythonCallBackFunc成为模板化函数.

    template<class ReturnType>
    void pythonCallBackFunc(string inputStr){   
      Py_Initialize();
      try   
         {
        str boostInputStr(inputStr.c_str());
        object result = eval(boostInputStr);

        return extract<ReturnType>(result);

       //Py_Finalize() #not calling because of the boost.python
          } 
          catch(error_already_set const &)
          {
       //do somthing
          }
     }
Run Code Online (Sandbox Code Playgroud)

...在这种情况下,您必须使用适当的类型调用它,例如

       pythonCallBackFunc<int>(inputStr);
Run Code Online (Sandbox Code Playgroud)

希望这对你有所帮助.