微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在python和c ++之间传递二进制数据

如何解决在python和c ++之间传递二进制数据

问题可能是缓冲:认情况下,Cstdio缓冲所有写入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;
}

请注意,您必须指定要从子进程中读取的字节数,否则程序将阻塞以等待更多输出。如果这困扰您,请尝试解决此问题的方法之一

解决方法

我一直在使用Python 2.7开发QGIS的插件,在我实际去映射层上进行一些图像处理之前,它工作正常。甚至收集栅格图层的RGB值(例如5k x
1k的部分)之类的简单任务也需要一点时间(约2分钟)。如果需要,我可以忍受,但是当我开始计算数据的简单指标(如熵)时,处理所需的时间便激增了(我在大约40分钟无响应的分钟后停止了处理)。

我以前用C
++编写过Entropy代码,希望能够以这种方式处理数据。经过研究后,我发现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,stdout)

将数据通过管道传输回python,但没有成功。我认为部分问题可能是文本版本使用cin并等待EOL指示器。我不清楚在二进制数据的情况下如何做类似的事情。

我想知道如何修改上面的示例代码,以将int从python程序发送到c 程序。在c
程序中增加int,然后将该int发送回python程序。请记住,如果您对建议的解决方案提出警告,则我将必须一次处理数百万个整数。

如果无法解决问题,我将继续让python写出一个C ++代码读取的二进制文件,但如果可能的话,我真的很想使用这种方法。

感谢您的提前帮助。

更新 Roland的解决方案是我需要的起点。对于后来的人,下面是我上面描述的代码的有效原型。这是罗兰(Roland)

Python驱动程序:

import subprocess

proc = subprocess.Popen("C:\Python27\PythonPipes.exe",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]
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,stdin);
        if ('q' == buf)
            break;
        increase = buf + 1;
        fwrite(&increase,stdout);
        fflush(stdout);
    }

    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。