我一直在使用Python 2.7编写QGIS插件,该工作正常,直到我真正去映射图层上进行一些图像处理。即使是简单的任务,例如收集栅格图层的RGB值(比如一个5k x 1k的部分)也需要一点时间(约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 ++代码读入的二进制文件,但我真的很想使用这种方法,如果它&#39可能。
提前感谢您的帮助。
更新 Roland的解决方案是我需要的起点。对于那些后来来的人,我上面描述的代码的工作原型如下。这是罗兰的一个小修改
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;
}
答案 0 :(得分:4)
问题可能是缓冲:默认情况下,C stdio缓冲写入stdout的所有内容,并且仅在写入换行符时将缓冲区刷回管道(行缓冲)。写完后拨打Class1
时问题就消失了。您还可以通过fflush(stdout)
中定义的setvbuf
功能禁用(或控制)缓冲,例如使用<stdio.h>
完全禁用缓冲。
我已经使用以下两个程序测试了第一个变体:
setvbuf(stdout, NULL, _IONBF, 0)
和一个小C程序:
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()
请注意,您必须指定要从子进程读回的字节数,否则程序将阻塞,等待更多输出。如果这困扰你,请尝试this question的其中一个解决方案。