2010-03-16 6 views
7

Attualmente sto usando Boost.Process dalla sandbox Boost, e sto riscontrando problemi nel riuscire a catturare correttamente il mio output standard; chiedendosi se qualcuno possa darmi un secondo paio di occhi in quello che potrei fare male.Impossibile acquisire l'output standard del processo utilizzando Boost.Process

Sto cercando di estrarre le miniature dalle immagini RAW della fotocamera utilizzando DCRAW (versione più recente) e acquisirle per la conversione in QT QImage.

La funzione di lancio processo:

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++; 
    } 
} 

Invocare il convertitore:

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

L'obiettivo è quello di verificare semplicemente che posso copiare il flusso di input un file di output.

Attualmente, se io commento la riga seguente:

args.push_back("-c"); 

poi la miniatura è scritto da dcraw alla directory di origine con un nome di CFK_2439.thumb.jpg, che mi dimostra che il processo è essere invocato con gli argomenti giusti. Quello che non sta succedendo è il collegamento alla pipe di uscita correttamente.

FWIW: Sto eseguendo questo test su Windows XP in Eclipse 3.5/Latest MingW (GCC 4.4).

[UPDATE]

Da debugging, sembrerebbe che dal momento in cui il codice raggiunge copia del flusso, il file/tubo è già chiuso - byte = input.readsome (...) non è mai un valore diverso da 0.

+0

Probabilmente non è il problema principale, ma il 'output''ofstream' dovrebbero essere aperti in modalità binaria. Inoltre: 'streamcopy' potrebbe essere semplificato in' out << input.rdbuf(); ' –

+0

Good call on input.rdbuf(). Lo stavo effettivamente usando prima di scrivere streamcopy per vedere cosa stava succedendo sotto il cofano. –

risposta

3

Bene, penso che sia necessario reindirizzare correttamente il flusso di output. Nella mia applicazione qualcosa come questo funziona:

[...] 

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(); 

[...] 

Senza il reindirizzamento del stdout andrà da nessuna parte, se non ricordo male. È buona norma attendere il termine del processo se si desidera ottenere l'intero risultato.

EDIT:

Sono su Linux con forse una vecchia versione di boost.process. mi rendo conto che il tuo codice è simile allo snippet che ti ho dato. Il c.wait() potrebbe essere la chiave ...

EDIT: Boost.process 0.1 :-)

1

Se la migrazione a "l'ultima" boost.process non è un problema (come sapete sicuro , ci sono diverse varianti per questa libreria), è possibile utilizzare il seguente (http://www.highscore.de/boost/process0.5/)

file_descriptor_sink sink("stdout.txt"); 
execute(
    run_exe("test.exe"), 
    bind_stdout(sink) 
); 
Problemi correlati