Sem*_*ape 6 c++ python pipe python-2.7
我一直在使用 Python 2.7 开发 QGIS 插件,它工作得很好,直到我真正去对映射图层进行一些图像处理。即使是收集栅格图层(例如 5k x 1k 部分)的 RGB 值等简单任务也需要一点时间(约 2 分钟)。如果必须的话,我可以忍受这一点,但是当我开始计算数据的简单指标(例如熵)时,处理所需的时间就会激增(我在大约 40 分钟无响应后停止了处理)。
我之前用 C++ 编写过熵代码,并且希望能够以这种方式处理数据。经过一些研究后,我发现 Python 可以使用 stdin 和 stdout 来传输数据,并在http://ubuntuforums.org/archive/index.php/t-524072.html的论坛中发现了以下示例
使用此 Python 代码作为驱动程序
import subprocess
proc = subprocess.Popen("C:\Python27\PythonPipes.exe",
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
state = "run"
while state == "run":
    input = raw_input("Message to CPP>> ")
    if input == "quit":
        state = "terminate" # any string other than "run" will do
    proc.stdin.write(input + "\n")
    cppMessage = proc.stdout.readline().rstrip("\n") 
    print "cppreturn message ->" + cppMessage + " written by python \n"
这个 C++ 代码作为数据处理器
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* args[]){
    string python_message = "";
    bool quit = false;
    while (!quit){
        cin >> python_message;
        if (python_message == "quit"){
            quit = true;
        }
        else if (python_message == "first"){
            cout << "First Hello!" << endl;
        }
        else if (python_message == "second"){
            cout << "Second Hello!" << endl;
        }
        else if (python_message == "third"){
            cout << "Third Hello!" << endl;
        }
        else {
            cout << "Huh?" << endl;
        }
    }
    return 0;
}
该代码非常适合文本数据。我可以用它来来回传输文本一整天。但我想要做的是来回传递二进制数据,以便我可以将整数栅格图层数据从python发送到c++进行处理,然后返回结果。
我环顾四周并尝试了将字节缓冲区放入的各种组合
proc.stdin.write(bufferdata)
并使用
fread(Arraypointer, 4,1,stdin) 
用于在 C++ 程序端接收缓冲区数据以及
fwrite(outArraypointer,4,1,stdout)
将数据传输回 python,但尚未成功。我认为部分问题可能是文本版本使用cin并等待EOL指示器。我不清楚在二进制数据的情况下如何做类似的事情。
我想知道如何修改上面的示例代码以将 int 从 python 程序发送到 c++ 程序。在 C++ 程序中递增 int,然后将该 int 发送回 python 程序。请记住,我将不得不一次对数百万个整数执行此操作,以防对您提出的解决方案提出警告。
如果这不起作用,我将转向只让 python 写出 C++ 代码读入的二进制文件,但如果可能的话,我真的很想使用这种方法。
感谢您提前的帮助。
更新罗兰的解决方案是我需要的起点。对于后来的人来说,我上面描述的代码的工作原型如下。它是对罗兰的稍加修改
Python 驱动程序:
import subprocess
proc = subprocess.Popen("C:\Python27\PythonPipes.exe",
stdin=subprocess.PIPE,stdout=subprocess.PIPE)
s1 = bytearray(10)   
s1[0] = 65 #A
s1[1] = 66 #B
s1[2] = 67 #C
s1[3] = 68 #D
s1[4] = 69 #E
s1[5] = 70 #F
s1[6] = 71 #G
s1[7] = 72 #H
s1[8] = 73 #I
t = buffer(s1)       
proc.stdin.write(t)
value = [0,0,0,0,0,0,0,0]
for i in range(8):
    value[i] = ord(proc.stdout.read(1))
    print "value i -> " + str(value[i])
proc.stdin.write('q')
proc.wait()
C++处理器
#include <stdio.h>
char increase;
int main(int argc, char **argv) {
    for (;;) {
        char buf;
        fread(&buf, 1, 1, stdin);
        if ('q' == buf)
            break;
        increase = buf + 1;
        fwrite(&increase, 1, 1, stdout);
        fflush(stdout);
    }
    return 0;
}
问题可能是缓冲:默认情况下,C stdio 缓冲写入 stdout 的所有内容,并仅在写入换行符时将缓冲区刷新回管道(行缓冲)。写完后打电话,问题就消失了fflush(stdout)。您还可以通过setvbuf中定义的函数禁用(或控制)缓冲<stdio.h>,例如使用setvbuf(stdout, NULL, _IONBF, 0)完全禁用缓冲。
我已经使用以下两个程序测试了第一个变体:
import subprocess
proc = subprocess.Popen("./echotest",
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE)
proc.stdin.write('abc')
message = proc.stdout.read(3)
print "return message ->" + message + " written by python \n" 
proc.stdin.write('q')
proc.wait()
和一个小 C 程序:
#include <stdio.h>
int main (int argc, char **argv) {
    for (;;) {
        char buf;
        fread(&buf, 1, 1, stdin);
        if ('q' == buf)
            break;
        fwrite(&buf, 1, 1, stdout);
        fflush(stdout);
    }
    return 0;
}
请注意,您必须指定要从子进程读回多少字节,否则程序将阻塞,等待更多输出。如果这让您感到困扰,请尝试该问题的解决方案之一。