2014-05-15 22 views
5

Sto provando a richiamare un'applicazione da un'altra in C++. L'app incorporata è soggetta a errori di segmentazione a causa di errori di sintassi da un file di input, pertanto il programma esterno sarà responsabile della ripetizione dell'interno e dei problemi di registrazione.Confusione del valore di ritorno dall'applicazione incorporata

La mia idea immediata era di fare affidamento sul valore di ritorno del programma interno. Così ho iniziato a sperimentare con quello. Ho scritto un programma fittizio in Inner.cpp:

#include <iostream> 

int main() 
{ 
    std::cout << "Inner" << std::endl; 
    return 22; 
} 

Poi, ho scritto questo in Outer.cpp:

#include <cstdlib> 
#include <iostream> 

int main() 
{ 
    int retval = system("~/Inner"); 
    std::cout << "Returned: " << retval << std::endl; 
    return 0; 
} 

Ha ottenuto questo output di confusione:

Inner 
Returned: 5632 

Così ho iniziato a leggere. Ho presto scoperto che solo gli 8 bit LS passano, che sono trattati senza segno. Ma questo non significherebbe solo non usare valori superiori a 255? Perché ricevo questo strano valore?

Così ho iniziato a guardare i bit.

What I expected: 22 -> 0000 0000 0000 0000 0000 0000 0001 0110 
What I got: 5632 -> 0000 0000 0000 0000 0001 0110 0000 0000 

Woah, è lo stesso schema, appena spostato. E infatti, quando ho modificato la mia linea a:

std::cout << "Returned: " << (retval >> 8) << std::endl; 

ho sempre avuto il numero esatto che volevo. Tuttavia, non riesco a trovare nulla sul perché questo sta accadendo, e ora sono preoccupato, che ci sono molte più sorprese quando arrivo alla parte in cui ho bisogno di rilevare un SIGSEGV nel programma interno, e continuare l'esecuzione nell'esterno.

La mia domanda, in ultima analisi, è: qual è il modo migliore per incorporare in modo sicuro un'applicazione (a riga di comando) in un'altra, considerando che devono comunicare alcuni dati minimi e quella invocata potrebbe terminare con il segfaulting? (Inoltre, che cosa è questa cosa Bitshift con il valore di ritorno?)

Ubuntu 12.04.4 LTS 
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 
+1

Perché non correggere gli errori nell'applicazione incorporata in modo che non si blocchi? –

+0

@PaulR Non ci sono bug. Funziona con enormi file di input provenienti da fonti esterne, non c'è tempo per eseguire la scansione e controllare tutti gli errori di sintassi prima dell'analisi. – Innkeeper

+1

Se l'app si arresta in modo anomalo quando non riesce a gestire un errore di sintassi nel file di input, allora chiamerei un bug piuttosto serio. –

risposta

2

Si desidera utilizzare fork, exec e wait, qualcosa come:

int status; 
if ((pid = fork()) == 0) // child proc 
    exec("~/Inner"); 
else // parent 
    waitpid(-1, &status, 0) 
1

Usa WEXITSTATUS

int retval = system("~/Inner"); 
retval = WEXITSTATUS(retval); 

farà