0

这需要一点解释。请多多包涵。

我有的

我拥有一些 Fortran 源代码和一些从该代码编译的二进制文件。我没有进行编译,但是有一个构建脚本建议使用 G77 来进行编译。

除了 Fortran 的东西,还有一些 Java 代码为用户提供了一个围绕二进制文件的 GUI“包装器”。它通过输入/输出/错误管道在自身和二进制文件之间传递信息。Java 代码非常混乱,这种处理方式增加了很多样板文件和冗余,但它完成了工作,我知道它有效。

我需要的

不幸的是,我想做一些改变:

  1. 我想为二进制文件创建一个新的 Python 包装器(或者,更准确地说,扩展现有的 Python 程序以成为新的包装器)。

  2. 我希望能够将 Fortran 代码编译为现有程序构建过程的一部分。我想为此使用 gfortran,因为 MinGW 在构建中的其他地方使用,因此很容易获得。

问题

当我使用 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命令,但是代码甚至没有更改来执行该部分,所以我还不担心。

额外信息

  • 我必须用-ffixed-line-length-132标志调用 gfortran 以便代码编译,但除此之外我不使用其他任何东西。我曾尝试-ff2c模糊地使用该标志,希望它会有所作为。它没有。

  • 这篇stackoverflow 帖子内容丰富,但没有为我提供任何有用的信息。

  • 相关手册页表明 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 回答