2010-03-16 5 views
7

В настоящее время я использую Boost.Process из изолированной области Boost, и у меня возникают проблемы с его получением для правильного вывода моего стандартного вывода; интересно, может ли кто-нибудь дать мне вторую пару глазных яблок в то, что я могу делать неправильно.Невозможно захватить стандартный вывод процесса с использованием Boost.Process

Я пытаюсь извлечь эскизы из изображений камеры RAW с помощью DCRAW (последняя версия) и захватить их для преобразования в QT QImage.

Функция запуска процесса:

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

Вызов преобразователя:

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

Цель состоит в том, чтобы просто убедиться, что я могу скопировать входной поток в выходной файл.

В настоящее время, если я закомментируйте следующую строку:

args.push_back("-c"); 

то миниатюра написана DCRAW в исходный каталог с именем CFK_2439.thumb.jpg, что доказывает мне, что этот процесс вызывается с правильными аргументами. То, что не происходит, правильно подключается к выходной трубке.

FWIW: Я выполняю этот тест в Windows XP под Eclipse 3.5/Latest MingW (GCC 4.4).

[UPDATE]

От отладки, может показаться, что к тому времени, когда код достигает копирование потока, файл/труба уже закрыта - байт = input.readsome (...) никогда любое значение кроме 0.

+0

Вероятно, не главная проблема, но 'output''ofstream' должен быть открыт в двоичном режиме. Кроме того: 'streamcopy' может быть упрощен в' out << input.rdbuf(); ' –

+0

Хороший запрос на input.rdbuf(). Я фактически использовал это, прежде чем писать потокопись, чтобы посмотреть, что происходит под капотом. –

ответ

3

Ну, я думаю, что вам нужно правильно перенаправить выходной поток. В моем приложении что-то вроде это работает:

[...] 

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

[...] 

без редиректа стандартного вывод никуда не уйдет, если я правильно помню. Хорошая практика - дождаться окончания процесса, если вы хотите получить весь результат.

EDIT:

Я на Linux с возможно старой версии boost.process. я понимаю, что ваш код похож на фрагмент, который я вам дал. C.wait() может быть ключом ...

EDIT: Boost.process 0,1 :-)

1

Если мигрирующие к «последним» boost.process не является проблемой (как вы уверены, что знаете есть несколько вариантов для этой библиотеки), вы можете использовать следующие (http://www.highscore.de/boost/process0.5/)

file_descriptor_sink sink("stdout.txt"); 
execute(
    run_exe("test.exe"), 
    bind_stdout(sink) 
); 
Смежные вопросы