簡體   English   中英

python和c++之間的管道二進制數據

[英]piping binary data between python and c++

我一直在使用 Python 2.7 開發 QGIS 的插件,它工作正常,直到我實際對映射層進行一些圖像處理。 即使是像收集光柵層(比如 5k x 1k 部分)的 RGB 值這樣的簡單任務也需要一點時間(~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,4,1,stdout)

將數據管道回 python,但沒有成功。 我認為部分問題可能是文本版本使用cin並等待EOL指標。 我不清楚如何在二進制數據的情況下做類似的事情。

我想知道如何修改上面的示例代碼以將 int 從 python 程序發送到 c++ 程序。 在 c++ 程序中增加 int,然后將該 int 發送回 python 程序。 請記住,我將不得不一次處理數百萬個整數,以防對您提出的解決方案提出警告。

如果這不起作用,我將轉而讓 python 寫出一個 C++ 代碼讀入的二進制文件,但如果可能的話,我真的很想使用這種方法。

提前感謝您的幫助。

更新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;
}

問題可能是緩沖:默認情況下,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;
}

請注意,您必須指定要從子進程讀回的字節數,否則程序將阻塞,等待更多輸出。 如果這讓您感到困擾,請嘗試解決此問題的方法之一

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM