Встраивание Python 3.3 в программу на C ++ при одновременном считывании только одной строки из ввода

В настоящее время я работаю над добавлением встроенной поддержки Python (и да, расширение не вариант) в большую программу в рамках моей летней практики. В идеале, я могу сохранить поддержку Python в одном .DLL, который в настоящее время содержит собственный скриптовый язык программы и является самым простым местом для интеграции указанного языка и Python.

Тем не менее, из-за API программы, у меня есть только одна функция ввода для использования. Возвращаемое значение этой функции — одна строка из текущего ввода, которая может быть консолью или файлом. Входной интерфейс не может (внутри .DLL) быть преобразован в объект потока, буфер или указатель FILE.

Мой текущий тестовый код (написанный вне программы с использованием 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;

Я не сталкивался с серьезными проблемами с этим взломом, но он кажется мне ужасно не элегантным. Кто-нибудь может придумать лучший способ сделать это?

Я уже очистил библиотеки boost.python с моим боссом, если это предложит мне полезную хитрость, которая ускользнула от меня.

РЕДАКТИРОВАТЬ: я, вероятно, должен упомянуть, что сама программа, хотя не мой скудный испытательный стенд, должен работать на MS Windows.

0

Решение

То, что вы написали, будет внешне похоже на стандартный интерпретатор, но оно не будет следовать тем же правилам отступа / отступа и продолжения для любого, кроме самых тривиальных случаев.

Самый простой способ встроить оболочку интерактивного интерпретатора — встроить пустой интерпретатор, который запускает интерактивный интерпретатор, написанный на чистом Python, обычно через code модуль.

Для того, чтобы это работало, вам нужно будет подключить ваш построчный ридер к встроенному stdin объект файла, но, похоже, для любого реалистичного использования вы все равно захотите этого. (В противном случае, что произойдет, если, например, пользователь введет input() на скорлупе?)

Альтернативой является создание pty и запустите стандартный интерактивный интерпретатор против этого (возможно, как дочерний процесс), подавая входную трубу pty из вашей программы чтения строк.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]