Различия при записи / чтении из консоли между кодом, скомпилированным gfortran и g77
Это займет немного объяснений. Пожалуйста, потерпите меня.
Что я имею
У меня есть некоторый исходный код на Фортране и несколько двоичных файлов, скомпилированных из этого кода. Я не делал компиляцию, но есть сценарий сборки, который предполагает, что G77 был использован для этого.
Помимо фортрановского контента, есть также некоторый Java-код, который предоставляет пользователям GUI-оболочку для двоичных файлов. Он передает информацию между собой и двоичными файлами через их каналы ввода / вывода / ошибки. Java-код очень грязный, и такой способ работы добавляет много шаблонного и избыточного, но он делает свою работу, и я знаю, что это работает.
Что мне нужно
К сожалению, я хотел бы внести некоторые изменения:
Я хочу создать новую оболочку Python для двоичных файлов (или, точнее, расширить существующую программу Python, чтобы она стала новой оболочкой).
Я хочу иметь возможность компилировать код на Фортране как часть процесса сборки этой существующей программы. Я хотел бы использовать gfortran для этого, так как MinGW используется в другом месте сборки, и поэтому он будет легко доступен.
Эта проблема
Когда я сам компилирую код Fortran, используя gfortran, я не могу заставить полученные двоичные файлы "общаться" ни с текущей оболочкой Java, ни с моей новой оболочкой Python.
Вот различные способы печати на консоли, которые я пробовал в коде Фортрана:
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
команды, но в коде даже нет изменений для выполнения этой части, поэтому я пока не беспокоюсь об этом.
Дополнительная информация
Я должен позвонить Gfortran с
-ffixed-line-length-132
флаг, чтобы код компилировался, но кроме этого я больше ничего не использую. Я пытался использовать-ff2c
флаг в смутной надежде, что это будет иметь значение. Это не так.Эта статья о стековом потоке является информативной, но не предлагает мне ничего, что работает.
Соответствующая страница руководства предполагает, что printA должен работать просто отлично.
Я работаю над Windows, но это нужно для мультиплатформенности.
Juse, в случае, если вы прошли проверку, код Java использует
Runtime.getRuntime().exec("prog.exe")
вызвать двоичные файлы, а затем различные "потоковые" методы результирующегоProcess
объект для общения с ними. Код Python использует эквиваленты этого, предоставленныеPopen
объектsubprocess
модуль.Я должен также сказать, что я знаю, что есть альтернативы. Переписывание кода на Python (или что-то еще, например, C++) или внесение изменений, чтобы он мог вызываться через F2Py, были исключены в качестве опций. Использование g77 также не допускается; у нас достаточно зависимостей как есть. Я хотел бы иметь возможность писать / читать с консоли должным образом с помощью gfortran или знать, что это просто невозможно.
1 ответ
Трудно сказать, не видя больше деталей из ваших кодов Фортрана и 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()