从C ++调用Python脚本并使用其输出

时间:2022-12-31 01:13:24

I want to call a python script from C++ and wish to use the output .csv file generated by this script back into C++. I tried this in main():

我想从C ++调用一个python脚本,并希望将此脚本生成的输出.csv文件重新用于C ++。我在main()中试过这个:

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

This does call and execute the python script.

这会调用并执行python脚本。

The print commands in the Python are being executed. Things are being printed on the screen when the script is called. So far so good. However, it is not creating the .csv file (part of the same script).

正在执行Python中的打印命令。调用脚本时,屏幕上会打印出一些内容。到现在为止还挺好。但是,它不会创建.csv文件(同一脚本的一部分)。

Example: I had a training.csv file with 100 entries. I called the Python script, with little changes to the script so that the training.csv file now should contain only 50 entries instead of 100. It’s overwritten. However, no such thing happening. Rest of the commands in the script (print, etc) are working perfectly.

示例:我有一个包含100个条目的training.csv文件。我调用了Python脚本,对脚本几乎没有任何更改,因此training.csv文件现在应该只包含50个条目而不是100个。它被覆盖了。但是,没有这样的事情发生。脚本中的其他命令(打印等)工作正常。

The training.csv file is to be read with C++ normally using fstream and getline.

使用fstream和getline通常使用C ++读取training.csv文件。

Any idea how to do it (using Linux)?

知道怎么做(使用Linux)吗?

2 个解决方案

#1


17  

Here is a solution to embed the execution of your python module from within your C++ application. It's not better or worst than forking/executing your python script through a system call, it just is a different way to do it. Whether it is best or not depend on your context and usage.

这是一个从C ++应用程序中嵌入python模块执行的解决方案。它并不比通过系统调用分支/执行你的python脚本更好或更差,它只是一种不同的方式。是否最佳取决于您的背景和用法。

Some time ago I have coded a way to load python modules as plugins to a C++ application, here's the interesting part.

前段时间我编写了一种将python模块作为插件加载到C ++应用程序的方法,这是有趣的部分。

Basically, you need to #include <Python.h>, then Py_Initialize() to start your python interpreter.

基本上,你需要#include ,然后Py_Initialize()来启动你的python解释器。

Then you do import sys, using : PyRun_SimpleString("import sys");, and you can load your plugin by doing PyRun_SimpleString('sys.path.append("path/to/my/module/")').

然后使用:PyRun_SimpleString(“import sys”);导入sys,你可以通过执行PyRun_SimpleString('sys.path.append(“path / to / my / module /”)')加载你的插件。

To exchange values between C++ and Python, things get harder, you have to to transform all your C++ objects into python objects (starting line 69 in my script).

要在C ++和Python之间交换值,事情会变得更加困难,你必须将所有的C ++对象转换为python对象(在我的脚本中从第69行开始)。

Then you can call your function using PyObject_Call_Object(...), using all the python objects you created as arguments.

然后,您可以使用PyObject_Call_Object(...)调用您的函数,使用您创建的所有python对象作为参数。

You get the return value, and transforms all those values in C++ objects. And don't forget the memory management in all that!

您将获得返回值,并在C ++对象中转换所有这些值。并且不要忘记所有内存管理!

To end your python interpreter, a simple call to Py_Finalize().

要结束python解释器,只需调用Py_Finalize()即可。

It really looks harder than it is really, but you have to be really careful doing this, because it could lead to leaks, security issues etc..

它看起来真的比实际看起来更难,但你必须非常小心这样做,因为它可能导致泄漏,安全问题等。

#2


5  

Try using POSIX's popen() instead of system(). It pipes stdin/stdout of child process to returned file handle.

尝试使用POSIX的popen()而不是system()。它将子进程的stdin / stdout传递给返回的文件句柄。

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

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

pclose(in);

#1


17  

Here is a solution to embed the execution of your python module from within your C++ application. It's not better or worst than forking/executing your python script through a system call, it just is a different way to do it. Whether it is best or not depend on your context and usage.

这是一个从C ++应用程序中嵌入python模块执行的解决方案。它并不比通过系统调用分支/执行你的python脚本更好或更差,它只是一种不同的方式。是否最佳取决于您的背景和用法。

Some time ago I have coded a way to load python modules as plugins to a C++ application, here's the interesting part.

前段时间我编写了一种将python模块作为插件加载到C ++应用程序的方法,这是有趣的部分。

Basically, you need to #include <Python.h>, then Py_Initialize() to start your python interpreter.

基本上,你需要#include ,然后Py_Initialize()来启动你的python解释器。

Then you do import sys, using : PyRun_SimpleString("import sys");, and you can load your plugin by doing PyRun_SimpleString('sys.path.append("path/to/my/module/")').

然后使用:PyRun_SimpleString(“import sys”);导入sys,你可以通过执行PyRun_SimpleString('sys.path.append(“path / to / my / module /”)')加载你的插件。

To exchange values between C++ and Python, things get harder, you have to to transform all your C++ objects into python objects (starting line 69 in my script).

要在C ++和Python之间交换值,事情会变得更加困难,你必须将所有的C ++对象转换为python对象(在我的脚本中从第69行开始)。

Then you can call your function using PyObject_Call_Object(...), using all the python objects you created as arguments.

然后,您可以使用PyObject_Call_Object(...)调用您的函数,使用您创建的所有python对象作为参数。

You get the return value, and transforms all those values in C++ objects. And don't forget the memory management in all that!

您将获得返回值,并在C ++对象中转换所有这些值。并且不要忘记所有内存管理!

To end your python interpreter, a simple call to Py_Finalize().

要结束python解释器,只需调用Py_Finalize()即可。

It really looks harder than it is really, but you have to be really careful doing this, because it could lead to leaks, security issues etc..

它看起来真的比实际看起来更难,但你必须非常小心这样做,因为它可能导致泄漏,安全问题等。

#2


5  

Try using POSIX's popen() instead of system(). It pipes stdin/stdout of child process to returned file handle.

尝试使用POSIX的popen()而不是system()。它将子进程的stdin / stdout传递给返回的文件句柄。

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

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

pclose(in);