在 Python 和 C++ 之间管道二进制数据
piping binary data between python and c++
我一直在使用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:Python27PythonPipes.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,但 NOPT 已经成功了。我认为部分问题可能是文本版本使用 cin 并等待 EOL 指标。我不清楚在二进制数据的情况下如何做类似的事情。
我想知道如何修改上面的示例代码以将 int 从 python 程序发送到 c++ 程序。 递增 C++ 程序中的 int,然后将该 int 发送回 Python 程序。 请记住,我将不得不一次使用数百万个整数来执行此操作,以防对您提出的解决方案提出警告。
如果这不起作用,我将只让 python 写出一个 c++ 代码读取的二进制文件,但如果可能的话,我真的很想使用这种方法。
提前感谢您的帮助。
更新罗兰的解决方案是我需要的起点。对于那些后来的人,下面就是我上面描述的代码的工作原型。这是对罗兰的轻微修改
蟒蛇驱动程序:
import subprocess
proc = subprocess.Popen("C:Python27PythonPipes.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)
时,问题消失了。您还可以通过<stdio.h>
中定义的setvbuf
函数禁用(或控制)缓冲,例如使用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;
}
请注意,您必须指定要从子进程读回多少字节,否则程序将阻塞,等待更多输出。如果这困扰您,请尝试此问题的解决方案之一。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 有根的二进制搜索树.保留与其父级的链接
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 多态二进制函数
- IPC使用多个管道和分支进程来运行Python程序
- 正在读取二进制文件(is_open)
- visual在c++中将十进制数转换为二进制数
- C++十进制到二进制,如何转换
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为什么二进制搜索在我的测试中不起作用
- 重载==不适用于二进制树
- 正在尝试重载二进制搜索树分配运算符
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 带有数组键C++的二进制映射
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 在 Python 和 C++ 之间管道二进制数据