0

これは少し説明が必要です。我慢してください。

私が持っているもの

私はいくつかの Fortran ソース コードと、そのコードからコンパイルされたいくつかのバイナリを所有しています。私はコンパイルを行いませんでしたが、G77 を使用してコンパイルしたことを示唆するビルド スクリプトがあります。

Fortran のものと同様に、バイナリの周りに GUI の「ラッパー」をユーザーに提供する Java コードもあります。入力/出力/エラー パイプを介して、自身とバイナリの間で情報を渡します。Java コードは非常に乱雑で、この方法では多くの定型文と冗長性が追加されますが、それは仕事をし、機能することを私は知っています。

私が必要なもの

残念ながら、いくつかの変更を加えたいと思います:

  1. バイナリ用の新しい Python ラッパーを作成したい (より正確には、既存の Python プログラムを拡張して新しいラッパーにしたい)。

  2. この既存のプログラムのビルド プロセスの一部として Fortran コードをコンパイルできるようにしたいと考えています。MinGW はビルドの他の場所で使用されているため、すぐに利用できるため、これには gfortran を使用したいと思います。

問題

gfortran を使用して自分で Fortran コードをコンパイルすると、結果のバイナリを現在の 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ますが、その部分を実行するためのコードも変更されていないので、まだ心配していません。

追加情報

  • コードがコンパイルされるように、フラグを指定して gfortran を呼び出す必要があり-ffixed-line-length-132ますが、それ以外には何も使用しません。私は-ff2c漠然とした希望で旗を使ってみました。そうではありません。

  • このスタックオーバーフローの投稿は有益ですが、機能するものは何も提供しません。

  • 関連するマニュアルページは、printA が問題なく動作することを示唆しています。

  • 私は Windows で作業していますが、これをマルチプラットフォームにする必要があります。

  • 参考までに、Java コードはRuntime.getRuntime().exec("prog.exe")バイナリを呼び出してから、結果のProcessオブジェクトのさまざまな「ストリーム」メソッドを呼び出してそれらと通信します。Python コードは、モジュールのPopenオブジェクトによって提供されるこれと同等のものを使用します。subprocess

  • また、代替手段があることは承知しています。Python (または C++ など) でコードを書き直すか、F2Py 経由で呼び出せるように修正することは、オプションとして除外されています。g77 を使用することもできません。そのままで十分な依存関係があります。gfortran を使用してコンソールに適切に書き込み/読み取りできるようにしたい、またはそれが不可能であることを知りたいです。

4

1 に答える 1

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

Fortran バイナリを呼び出す 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()
于 2013-11-20T21:06:58.630 に答える