web-dev-qa-db-ja.com

C ++からPythonスクリプトを呼び出し、その出力を使用する

C++からpythonスクリプトを呼び出し、このスクリプトによって生成された出力.csvファイルをC++に戻したい。私はこれをmain()で試しました:

std::string filename = "/home/abc/xyz/script.py";
std::string command = "python ";
command += filename;
system(command.c_str());

これは、pythonスクリプトを呼び出して実行します。

Python内のprintコマンドが実行されています。スクリプトが呼び出されると、画面に物が印刷されます。ここまでは順調ですね。ただし、.csvファイル(同じスクリプトの一部)は作成していません。

例:100エントリのtraining.csvファイルがありました。 Pythonスクリプトを呼び出しましたが、training.csvファイルに100ではなく50のエントリのみが含まれるように、スクリプトに少し変更を加えました。上書きされます。しかし、そのようなことは起きていません。スクリプト内の残りのコマンド(printなど)は完全に機能しています。

training.csvファイルは、通常fstreamおよびgetlineを使用してC++で読み取られます。

(Linuxを使用して)それを行う方法はありますか?

22
learner

以下に、C++アプリケーション内からpythonモジュールの実行を埋め込むためのソリューションを示します。pythonスクリプトを使用して、システムコールは、それを行うための別の方法であり、最適かどうかは、コンテキストと使用方法に依存します。

しばらく前に、C++アプリケーションへのプラグインとしてpythonモジュールをロードする方法をコーディングしました。これは 興味深い部分 です。

基本的に、#include <Python.h>、次にPy_Initialize()を使用してpythonインタープリターを開始する必要があります。

次に、_PyRun_SimpleString("import sys");を使用してimport sysを実行し、PyRun_SimpleString('sys.path.append("path/to/my/module/")')を実行してプラグインをロードできます。

C++とPythonの間で値を交換するには、事態が難しくなります。すべてのC++オブジェクトをpythonオブジェクト(スクリプトの69行目から)に変換する必要があります。

その後、PyObject_Call_Object(...)を使用して、引数として作成したすべてのpythonオブジェクトを使用して、関数を呼び出すことができます。

戻り値を取得し、C++オブジェクトのすべての値を変換します。そして、これらすべてのメモリ管理を忘れないでください!

pythonインタープリター、Py_Finalize()への単純な呼び出し]を終了します。

それは実際よりも実際に難しいように見えますが、漏れ、セキュリティ問題などにつながる可能性があるため、これを行うには本当に注意する必要があります。

18
zmo

popen()の代わりにPOSIXのsystem()を使用してみてください。返されるファイルハンドルに子プロセスのstdin/stdoutをパイプします。

FILE* in = popen(command.c_str(), "r");

fscanf(in, ... // or some other method of reading

pclose(in);
6
Vovanium