2010-03-16 6 views
7

Actualmente estoy usando Boost.Process del entorno limitado de Boost, y tengo problemas para lograr que capture mi salida estándar correctamente; preguntándome si alguien puede darme un segundo par de ojos en lo que podría estar haciendo mal.No se puede capturar la salida estándar del proceso usando Boost.Process

Estoy tratando de sacar imágenes en miniatura de imágenes de cámara RAW con DCRAW (última versión), y capturarlas para convertirlas a QT QImage.

La función de lanzamiento proceso:

namespace bf = ::boost::filesystem; 
namespace bp = ::boost::process; 

QImage DCRawInterface::convertRawImage(string path) { 
    // commandline: dcraw -e -c <srcfile> -> piped to stdout. 
    if (bf::exists(path)) { 
     std::string exec = "bin\\dcraw.exe"; 

     std::vector<std::string> args; 
     args.push_back("-v"); 
     args.push_back("-c"); 
     args.push_back("-e"); 
     args.push_back(path); 

     bp::context ctx; 
     ctx.stdout_behavior = bp::capture_stream(); 

     bp::child c = bp::launch(exec, args, ctx); 

     bp::pistream &is = c.get_stdout(); 
     ofstream output("C:\\temp\\testcfk.jpg"); 
     streamcopy(is, output); 
    } 
    return (NULL); 
} 


inline void streamcopy(std::istream& input, std::ostream& out) { 
    char buffer[4096]; 
    int i = 0; 
    while (!input.eof()) { 
     memset(buffer, 0, sizeof(buffer)); 
     int bytes = input.readsome(buffer, sizeof buffer); 
     out.write(buffer, bytes); 
     i++; 
    } 
} 

Invocando el convertidor:

DCRawInterface DcRaw; 
DcRaw.convertRawImage("test/CFK_2439.NEF"); 

El objetivo es verificar simplemente que puedo copiar el flujo de entrada a un archivo de salida.

Actualmente, si me comente la siguiente línea:

args.push_back("-c"); 

la vista en miniatura es escrita por DCRAW al directorio de origen con un nombre de CFK_2439.thumb.jpg, que me demuestra que el proceso es siendo invocado con los argumentos correctos. Lo que no está sucediendo es conectarlo correctamente a la tubería de salida.

FWIW: Estoy realizando esta prueba en Windows XP con Eclipse 3.5/Latest MingW (GCC 4.4).

[ACTUALIZACIÓN]

De depuración, parecería que en el momento en el código alcanza streamcopy, el archivo/tubería ya está cerrado - bytes = input.readsome (...) no es cualquier valor que no sea 0.

+0

Probablemente no es el tema principal, pero el 'output''ofstream' deben abrirse en modo binario. También: 'streamcopy' podría simplificarse en' out << input.rdbuf(); ' –

+0

Good call en input.rdbuf(). En realidad estaba usando eso antes de escribir streamcopy para ver qué sucedía debajo del capó. –

Respuesta

3

Bueno, creo que es necesario redirigir correctamente la secuencia de salida. En mi solicitud algo como esto funciona:

[...] 

bp::command_line cl(_commandLine); 
bp::launcher l; 

l.set_stdout_behavior(bp::redirect_stream); 
l.set_stdin_behavior(bp::redirect_stream); 
l.set_merge_out_err(true); 

bp::child c = l.start(cl); 
bp::pistream& is = c.get_stdout(); 

string result; 
string line; 
while (std::getline(is, line) && !_isStopped) 
{ 
    result += line; 
} 

c.wait(); 

[...] 

Sin la redirección de la salida estándar irá a ninguna parte si no recuerdo mal. Es una buena práctica esperar hasta el final del proceso si desea obtener el resultado completo.

EDIT:

estoy en Linux con quizás una versión antigua de boost.process. me di cuenta de que tu código es similar al fragmento que te di. El LLAM ESP OK() podría ser la clave ...

EDIT: Boost.process 0,1 :-)

1

Si la migración a la "última" boost.process no es un problema (como lo que sabes , hay varias variantes de esta biblioteca), se puede usar el siguiente (http://www.highscore.de/boost/process0.5/)

file_descriptor_sink sink("stdout.txt"); 
execute(
    run_exe("test.exe"), 
    bind_stdout(sink) 
); 
Cuestiones relacionadas