передача двоичных данных между Python и C ++
Я работал над плагином для QGIS с использованием Python 2.7, который работает нормально, пока я не приступлю к некоторой обработке изображений на отображенных слоях. Даже простые задачи, такие как сбор значений 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, но nopt не был успешным. Я думаю, что часть проблемы может заключаться в том, что текстовая версия использует cin и ждет индикатора EOL. Мне непонятно, как сделать нечто подобное в случае с двоичными данными.
Я хотел бы знать, как изменить приведенный выше пример кода для отправки int из программы на Python в программу на C ++. увеличьте int в программе c ++, а затем отправьте это int обратно в программу python. пожалуйста, имейте в виду, что мне придется делать это с миллионами целых раз за раз, если это будет связано с вашим предложенным решением.
Если это не сработает, я перейду к тому, чтобы python записал двоичный файл, в который читается код c ++, но я бы очень хотел использовать этот подход, если это возможно.
Спасибо за помощь заранее.
Обновить Решение Роланда было отправной точкой, в которой я нуждался. Для тех, кто придет позже, рабочий прототип кода, который я описал выше, приведен ниже. Это небольшая модификация Роланда
Python Driver:
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;
}