将输入传递给C++可执行python子进程。

7

我有一个C++可执行文件,在其中有以下代码行:

/* Do some calculations */
.
.
for (int i=0; i<someNumber; i++){
   int inputData;
   std::cin >> inputData;
   std::cout<<"The data sent from Python is :: "<<inputData<<std::endl;
   .
   .
   /* Do some more calculations with inputData */
}

而这个被循环调用的东西,我想在Python子进程中使用subprocess来调用这个可执行文件,就像这样:

p = Popen(['./executable'], shell=True, stdout=PIPE, stderr=PIPE, stdin=PIPE)

我可以通过可执行文件获取输出。

p.server.stdout.read()

但是我无法使用Python发送数据(整数)。
p.stdin.write(b'35')

由于 cin 在循环中被调用,因此 stdin.write 也应该被多次调用(在循环中)。上述情况是否可行?

有什么提示和建议可以帮助我实现它吗?谢谢。


天啊...我希望你的计算很复杂,否则可能用Python或C直接实现比这更快...如果它们很耗费资源,你应该考虑将C++编译成DLL甚至是Python库...(如果可以的话)一定要把用户输入从C代码中分离出来。 - Joran Beasley
@JoranBeasley 是的,我的计算在Python中很耗费资源。这就是我选择这样做的原因。此外,我需要与Python通信传输少量数据。 - AdityaG
1个回答

16

这里是一个简单的示例,演示如何从Python调用C++可执行文件并在Python中与其通信。

1)请注意,当向子进程的输入流(即 stdin )写入数据时,必须添加\n(就像手动运行程序时会按Rtn一样)。

2)还要注意刷新流,以便接收程序在打印结果之前不会被卡住等待整个缓冲区填充。

3)如果运行Python 3,请确保将字符串表示的流值转换为字节(参见https://dev59.com/5m035IYBdhLWcg3wW-pa#5471351)。

Python:

from subprocess import Popen, PIPE

p = Popen(['a.out'], shell=True, stdout=PIPE, stdin=PIPE)
for ii in range(10):
    value = str(ii) + '\n'
    #value = bytes(value, 'UTF-8')  # Needed in Python 3.
    p.stdin.write(value)
    p.stdin.flush()
    result = p.stdout.readline().strip()
    print(result)

C++:

#include <iostream>

int main(){
    for( int ii=0; ii<10; ++ii ){
        int input;
        std::cin >> input;
        std::cout << input*2 << std::endl;
        std::cout.flush();
    }
}

运行Python的输出:

0
2
4
6
8
10
12
14
16
18

非常感谢您的帮助。但不幸的是,我收到了一个错误,显示“TypeError:'str'不支持缓冲区接口”。... - AdityaG
1
@AdityaG 只需要更改为 p.stdin.write(b'35\n') ... 这样使用字节而不是字符串 (@Velimir 使用字符串,可能是不同的 Python 版本)。 - Joran Beasley
@Joran Beasley,你说得对。AdityaG,你一定在运行Python 3。在这种情况下,你必须将字符串转换为字节。我添加了一个注释来完成这个操作。 - Velimir Mlaker
@Velimir...还有一个小问题,你认为我们可以像那样发送numpy数组吗..?(我会尝试一下,只是好奇)。 - AdityaG
使用这种方法,您可以从Python流式传输任何想要的内容,只要您的C++可执行文件正确解析标准输入即可。但是理想情况下,您应该直接在Python中调用C++计算例程,通过包装C++代码(例如使用SWIG)并生成Python可调用函数来实现--创建子进程和流式传输字节并不是最佳选择。 - Velimir Mlaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接