如何调用在单独文件中定义的 Fortran 函数? [英] How to call a function in Fortran that is defined in a separate file?

查看:20
本文介绍了如何调用在单独文件中定义的 Fortran 函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to compile some really old code (1986 and before). This code references an external function. Today's compilers ask for far more code to make this work. And I keep failing. I now created a small hello world program, which demonstrates the problem.

你好.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

这不仅有一个,而且有两个问题:

This has not only one, but two problems:

  • 如何定义返回类型?文档告诉 <type>FUNCTION <function>FUNCTION <function>() <type>::<something> ,但都不起作用.
  • 如何让链接器找到函数?
  • How do I define the return type? Docs tell <type> FUNCTION <function> or FUNCTION <function> () <type>::<something> , but neither works.
  • How do I make the linker find the function?

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

gfortran -c func.for works (if I use the default return type real) and creates a mod file but linking does not work

$ 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.

__func_MOD_f is not contained in the mod file, but in the o file there is func.for__func_MOD_f.

有什么想法吗?

谢谢

推荐答案

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

You have two issues, the delcaration of f and properly linking the module.

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

First, compiling the module yields the error:

% 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 而不是隐式类型.添加:

This error is due to implicit typing of f and an incompatible assignment. Fixing this is simple, declare f explicitly as a character instead of an implicit type. Add:

character(len=30) :: f

到函数,现在你的模块编译了.这是修改后的模块:

to the function and now your module compiles. Here is the modified module:

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

<小时>

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


Your second problem is linking. Your command:

gfortran  hello.for  

失败,因为您没有指定模块对象.如果您已经编译了模块,您将指定:

fails because you did not specify the module object. If you already compiled the module you would specify:

gfortran hello.for func.o

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

if you were compiling them both at the same time you would do:

gfortran -o hworld func.for hello.for

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

if you are compiling everything individually:

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

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

Any of these will compile and run:

% ./hworld 
 Hello World!
 Hello Func   

<小时>

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


If you are modernizing your code, it would also be worth adding implicit none to avoid any implicit typing and declaring explicit variables for everything. e.g.:

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

这篇关于如何调用在单独文件中定义的 Fortran 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆