简体   繁体   English

将Python 3.3嵌入C ++程序中,但一次只能从输入读取一行

[英]Embedding Python 3.3 in a C++ program while only able to read one line at a time from input

I am currently working on adding embedded Python support (and yes, extending is not an option) to a large program as part of my summer internship. 作为暑期实习的一部分,我目前正在为大型程序添加嵌入式Python支持(是的,不能扩展)。 Ideally, I can keep the Python support within a single .DLL, which currently contains the program's in-house scripting language and is the easiest place to integrate said language and Python. 理想情况下,我可以将Python支持保留在单个.DLL中,该.DLL当前包含程序的内部脚本语言,并且是将所述语言与Python集成的最简单的地方。

However, due to the program's API, I only have a single input function to use. 但是,由于该程序的API,我只能使用一个输入函数。 This function's return value is a single line from the current input, which could be the console or a file. 该函数的返回值是当前输入的单行,可以是控制台或文件。 The input interface cannot (within the .DLL) be converted into a stream object, buffer, or FILE pointer. 无法将输入接口(在.DLL内)转换为流对象,缓冲区或FILE指针。

My current test code (written outside of the program, using std::string, istream, and getline to ape the restriction) is 我当前的测试代码(在程序外部编写,使用std :: string,istream和getline来遵守该限制)是

// start python
Py_Initialize();

try
{
   cout << "Python " << Py_GetVersion() << endl;
   string block;
   bool in_block = false;
   while ( !cin.eof() )
   {
      string str;
      cout << (in_block ? "... " : ">>> "); // prompt string
      getline(cin,str);

      if ( in_block ) // if in an indented block
      {
         if ( str.front() != ' ' && str.front() != '\t' ) // if ending the indented block
         {
            PyRun_SimpleString(block.c_str());  // run Python code contained in block string
            block.clear();                      // clear string for next block
            in_block = false;                   // no longer in block
         }
         else // a component of an indented block
         {
            block += (str+'\n'); // append input to block string
            continue;            // do not pass block exit code, do not collect two hundred dollars
         }
      }

      // either not in an indented block, or having just come out of one
      if ( str.back() == ':' ) // if colon, start new indented block
      {
         block = (str+'\n');
         in_block = true;
         continue;
      }
      else { PyRun_SimpleString(str.c_str()); } // otherwise, run block-free code
   }
}
catch ( error_already_set e ) { PyErr_Print(); }

// close python
Py_Finalize();

// done
return 0;

I have not encountered serious problems with this hack, but it strikes me as woefully inelegant. 我没有遇到过这种骇客的严重问题,但让我感到震惊,因为它非常卑鄙。 Can anyone think of a better way to do this? 谁能想到一种更好的方法呢?

I have already cleared the boost.python libraries with my boss, if that offers some useful trick that eluded me. 我已经和老板清除了boost.python库,如果它提供了一些让我难以理解的技巧。

EDIT: I should probably mention the program itself, while not my meagre testbed, must run on MS Windows. 编辑:我可能应该提到程序本身,虽然不是我微薄的测试平台,但必须在MS Windows上运行。

What you've written is going to look superficially similar to the stock interpreter, but it won't follow the same indent/dedent and continuation rules for any but the most trivial cases. 您写的内容看上去与股票解释器看起来很相似,但是除了最琐碎的情况外,它不会遵循相同的缩进/缩进和延续规则。

The easiest way to embed an interactive interpreter shell is to embed a bare interpreter that runs an interactive interpreter written in pure Python, usually via the code module. 嵌入交互式解释程序外壳的最简单方法是嵌入一个裸解释程序,该解释程序运行通过纯Python(通常通过code模块)编写的交互式解释code

For that to work, you will have to hook up your line-by-line reader to the embedded stdin file object, but it seems like for any realistic use you're going to want that anyway. 为此,您必须将逐行阅读器连接到嵌入式stdin文件对象,但是对于任何实际使用而言,无论如何您都希望这样做。 (Otherwise, what's going to happen if, eg, the user types input() at the shell?) (否则,例如,如果用户在外壳上键入input() ,将会发生什么?)

An alternative is to set up a pty and run the stock interactive interpreter against that (possibly as a child process), feeding the pty's input pipe from your line reader. 一种替代方法是设置一个pty并对其进行库存交互式解释器(可能是子流程),从生产线阅读器中输入pty的输入管道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM