2013-11-20 2 views
0

Это будет немного объяснять. Пожалуйста, несите меня.Различия при записи/чтении с консоли между gfortran- и g77-скомпилированным кодом

То, что я

У меня есть в моем распоряжении некоторого Fortran исходного кода и некоторые двоичные файлы, которые были собраны из этого кода. Я не делал компиляции, но есть сценарий сборки, который предлагает G77 для этого.

Как и материал Fortran, есть также некоторый Java-код, который предоставляет пользователям «оболочку» GUI вокруг двоичных файлов. Он передает информацию между собой и двоичными файлами через их каналы ввода/вывода/ошибок. Java-код очень грязный, и этот способ делать вещи добавляет много шаблонов и избыточности, но он выполняет эту работу, и я знаю, что это работает.

Что мне нужно

К сожалению, я хотел бы внести некоторые изменения:

  1. Я хочу, чтобы создать новый Python обертку для двоичных файлов (или, точнее, расширить существующий Python чтобы стать новой оболочкой).

  2. Я хочу, чтобы иметь возможность компилировать код Fortran как часть процесса сборки существующей программы. Я хотел бы использовать gfortran для этого, поскольку MinGW используется в другом месте сборки, и поэтому он будет легко доступен.

Проблема

Когда я компилировать код Fortran сам с помощью gfortran, я не могу получить результирующие двоичные файлы «говорить» либо текущей оболочки Java или мой новый Python обертке.

Вот различные способы печати на консоль, что я пытался в Fortran код:

subroutine printA(message) 
    write(6,*) message 
end 

subroutine printB(message) 
    write(*,*) message 
end 

subroutine printC(message) 
    use iso_fortran_env 
    write(output_unit,*) message 
end 

Есть также read команды, а также, но код даже не получить изменения, чтобы выполнить эта часть, поэтому я пока не беспокоюсь об этом.

Extra Info

  • Я должен позвонить gfortran с -ffixed-line-length-132 флагом, так что код компилируется, но кроме этого я ничего не использовать. Я попытался использовать флаг -ff2c в неопределенной надежде, что это изменит ситуацию. Это не так.

  • Этот stackoverflow post информативный, но не предлагает мне ничего, что сработает.

  • relavant manual page предполагает, что printA должен работать нормально.

  • Я работаю над Windows, но для этого потребуется многоплатформенная платформа.

  • Juse в случае, если вы заинтересованы, код Java использует Runtime.getRuntime().exec("prog.exe") для вызова двоичных файлов, а затем различные методы «потока» результирующего объекта Process для связи с ними.В коде Python используются эквиваленты, предоставленные объектом Popen модуля subprocess.

  • Я также должен сказать, что я знаю, что есть альтернативы. Переписывание кода в Python (или что-то еще похожее на C++) или внесение изменений, которые могут быть вызваны через F2Py, были исключены как опции. Использование g77 также не работает; у нас достаточно зависимостей. Я хотел бы иметь возможность правильно писать/читать с консоли с помощью gfortran или знать, что это просто невозможно.

+0

Для всего прочего, если сообщение является характером charater, вам необходимо его объявить. его целостность целостности как есть. – agentp

ответ

1

Трудно сказать, не видя более подробной информации из ваших кодов Fortran и Python. Следующая пара коды работает для меня (по крайней мере под Linux):

Fortran программы повторив свою входную строку префикса с номером строки:

program test_communication 
    use iso_fortran_env, stdout => output_unit, stdin => input_unit 
    implicit none 

    character(100) :: buffer 
    integer :: ii 

    ii = 1 
    do while (.true.) 
    read(stdin, *) buffer 
    write(stdout, "(I0,A,A)") ii, "|", trim(buffer) 
    flush(stdout) 
    ii = ii + 1 
    end do 

end program test_communication 

программа Python вызывающей Фортран двоичную. Вы можете кормить его произвольными строками с консоли.

import subprocess as sub 

print "Starting child" 
proc = sub.Popen("./a.out", stdin=sub.PIPE, stdout=sub.PIPE) 
while True: 
    send = raw_input("Enter a string: ") 
    if not send: 
     print "Exiting loop" 
     break 
    proc.stdin.write(send) 
    proc.stdin.write("\n") 
    proc.stdin.flush() 
    print "Sent:", send 
    recv = proc.stdout.readline() 
    print "Received:", recv.rstrip() 
print "Killing child" 
proc.kill() 
+0

Это помогает мне, поскольку это работает, когда я скомпилирую его! Я не уверен, что конкретно отличается (возможно, флеш-заявка), но этого достаточно, чтобы продолжить. Большое спасибо. Интересно, что я могу заставить свой код работать некоторое время, установив переменную окружения GFORTRAN_UNBUFFERED_ALL в 'y'. Это очень скоро происходит после этого. – JimmidyJoo

+0

Хорошо, «флеш» был ключевым здесь. – JimmidyJoo