【问题标题】:How to call a function in Fortran that is defined in a separate file?如何调用在单独文件中定义的 Fortran 函数?
【发布时间】:2015-08-28 19:06:56
【问题描述】:

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

你好.for

  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

有什么想法吗?

谢谢

【问题讨论】:

  • 在您的具体简单示例中,您只需将module..end module 放在program..end program 语句之前。在一个更复杂的例子中——可能在不同的文件夹中有不同的文件——你有几个选择。最简单的做法是将它们全部提供给您的编译器,例如gfortran file1.for file2.for
  • 在声明返回类型时也不清楚您遇到了什么问题。在这种情况下,您可以扩展您的示例代码吗?
  • 这是两个独立的文件。我无法用模块包装程序。我已经尝试在命令行上传递这两个文件。没用。
  • f='Hello Func' 不起作用,因为默认返回类型是 REAL。如何设置 CHARACTER?
  • 凯西的回答能解决你的问题吗?

标签: function linker fortran gfortran


【解决方案1】:

您有两个问题,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

【讨论】:

  • 抱歉,我没说清楚:这是两个独立的文件。我希望它们保持独立,因为还有 10 个其他程序引用了这个模块。
  • 使用-c单独编译其他文件,例如gfortran -c func.for
  • 非常感谢。数小时的尝试告一段落。我到底把implicit none放在哪里?
  • @JPT 在任何 use 语句之后和任何范围单元中的任何变量声明之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 2013-03-27
  • 2015-05-11
  • 1970-01-01
相关资源
最近更新 更多