Проблема связи между Java и приложением C ++ на stdin - PullRequest
1 голос
/ 17 июня 2009

У меня есть приложение Java, которое запускает приложение C ++ через API java.lang.Process, а затем пытается отправить ему команды через канал stdin:

process.getOutputStream().write("foo\n");
process.getOutputStream().flush();

На стороне C ++ работает цикл, который проверяет ввод в stdin и, если есть, это читает это. К сожалению, проверка всегда возвращает 0, следовательно, она никогда не пытается прочитать. Если я уберу проверку, она внезапно начнет видеть команды и обрабатывать их. Это на Linux.

Код приложений C ++ для проверки и чтения из stdin:

fd_set fds;
FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;


if( select ( 1, &fds, 0, 0, &tv ) > 0 ) {
    char buf[16384];
    buf[16383] = '\0';
    if ( fgets ( buf, sizeof ( buf ) - 1, stdin ) == 0 )
        return;
}

Как я уже сказал, удаление условия if заставляет его работать, но, конечно, это не так приятно, поскольку цикл вокруг него также делает некоторые другие вещи. Кто-нибудь понял, что я здесь не так делаю?

Обновление: Тем временем я смог воспроизвести проблему с двумя очень маленькими примерами приложений. Похоже, что проблема здесь связана с платформой Qt, как только я создаю экземпляр QCoreApplication, необходимый для этой инфраструктуры, тогда select () для stdin, похоже, больше не работает.

Ответы [ 5 ]

1 голос
/ 17 июня 2009

У вас есть два, если это; удаление какой заставляет это работать?

Разве fgets () не ждет новой строки, переполнения буфера или EOF перед его возвратом? Я не вижу, как вы пишете новую строку, «foo» не заполняет буфер, и поскольку поток не закрыт, он видит EOF?

0 голосов
/ 17 июня 2009

Находится ли ниже внутри цикла while? Если нет, то должно быть.

FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;

Если ответ на мой первый вопрос положительный, попробуйте этот тайм-аут:

tv.tv_sec = 0;
tv.tv_usec = 1;

Если вышеперечисленное не работает, попробуйте это:

while(fgets(buf, sizeof ( buf ) - 1, stdin) !=NULL) 
{ 
}
0 голосов
/ 17 июня 2009

Оказывается, это не приложение QCoreApplication, поскольку теперь я могу воспроизвести проблему дважды, не используя. Похоже, проблема в том, что я использую fgets (), а замена на read () исправляет это.

0 голосов
/ 17 июня 2009

Я помню, что было много споров по поводу семантики и операции select () и нескольких замен для нее. Вы можете посмотреть на них.

Как создается / открывается поток, который вы читаете? Это буферный поток? Возможно, вы ничего не получите, потому что это не было записано в поток, пока процесс записи не сбросит его?

Другая вещь, которую вы можете попробовать, - это поместить ее в поток с блокировкой ввода-вывода вместо опроса.

Удачи с этим

0 голосов
/ 17 июня 2009

Я могу ошибаться, но имеет ли смысл тайм-аут 0 для вызова select? Я бы попытался увеличить значение тайм-аута.

...