function - 如何调用 Fortran 中定义在单独文件中的函数?

标签 function linker fortran gfortran

我正在尝试编译一些非常古老的代码(1986 年及之前)。这段代码引用了一个外部函数。今天的编译器需要更多的代码才能完成这项工作。而我却一直失败。 我现在创建了一个小型的 hello world 程序,它演示了该问题。

你好。

  PROGRAM hello
    USE func        
    PRINT *, "Hello World!"
    PRINT *, f ()    
  END PROGRAM hello

func.for

  MODULE func
    PUBLIC f
  CONTAINS
    FUNCTION f () 
        f='Hello Func'
    END FUNCTION
  END MODULE

这不仅有一个问题,还有两个问题:

  • 如何定义返回类型?文档告诉<type> FUNCTION <function>FUNCTION <function> () <type>::<something> ,但两者都不起作用。
  • 如何让链接器找到该函数?

gfortran -c func.for有效(如果我使用默认返回类型 real)并创建一个 mod 文件,但链接不起作用

$ gfortran  hello.for 
/tmp/ccHNzcXA.o: In function `MAIN__':
hello.for:(.text+0xa4): undefined reference to `__func_MOD_f'
collect2: error: ld returned 1 exit status

__func_MOD_f 包含在 mod 文件中,但在 o 文件中有 func.for__func_MOD_f .

有什么想法吗?

谢谢

最佳答案

您有两个问题,f 的声明和正确链接模块。

首先,编译模块会产生错误:

% gfortran -c func.f
func.f:5:8:

       f='Hello Func'
        1
Error: Can't convert CHARACTER(1) to REAL(4) at (1)

此错误是由于 f 的隐式类型和不兼容的赋值造成的。解决这个问题很简单,将 f 显式声明为 character 而不是隐式类型。添加:

character(len=30) :: f

到该函数,现在您的模块已编译。这是修改后的模块:

  MODULE func
  PUBLIC f
  CONTAINS
  FUNCTION f ()
  character(len=30) :: f
  f='Hello Func'
  END FUNCTION
  END MODULE

你的第二个问题是链接。您的命令:

gfortran  hello.for  

失败,因为您没有指定模块对象。如果您已经编译了您需要指定的模块:

gfortran hello.for func.o

如果你同时编译它们,你会这样做:

gfortran -o hworld func.for hello.for

如果您单独编译所有内容:

gfortran -c func.for
gfortran -c hello.for
gfortran -o hworld hello.o func.o

其中任何一个都将编译并运行:

% ./hworld 
 Hello World!
 Hello Func   

如果您正在对代码进行现代化改造,那么还值得添加implicit none以避免任何隐式类型和为所有内容声明显式变量。例如:

module func
  implicit none
contains
function f 
  implicit none
  character(len=30) :: f
  f='Hello Func'
end function f
end module func

program hello
  use func
  implicit none        
  print *, "Hello World!"
  print *, f ()    
end program hello

关于function - 如何调用 Fortran 中定义在单独文件中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32278178/

相关文章:

python - 用 Python 读取 FORTRAN 格式的数字

R:更改省略号中的参数值并将省略号传递给其他函数,而无需使用list()和eval()

c - 如何修复 Makefile 错误?

c++ - 在静态类中初始化静态指针

c++ - 扩展 std::list

ruby - 为什么 Fortran 中的单元测试框架依赖于 Ruby 而不是 Fortran 本身?

bash - 将 bash 函数的返回值评估为整数

c++ - 如何将 char 类型数组传递给函数并将第一个 char 数组复制到第二个图表数组并使用 C++ 进行比较?

mysql from_days 产生意外结果

fortran - 从 Intel Fortran 调用 COM?