[英]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.