如何在 Fortran 界面中使用用户定义类型 [英] How to use a user-defined-type in a Fortran interface

查看:27
本文介绍了如何在 Fortran 界面中使用用户定义类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Fortran 2003 模块中,我定义了一个名为 t_savepoint 的类型,然后,我想为一个名为 fs_initializesavepoint 的子例程定义一个接口,它接受一个对象t_savepoint 类型的唯一参数.

In a Fortran 2003 module I'm defining a type called t_savepoint and, later, I want to define an interface for a subroutine called fs_initializesavepoint, which takes an object of type t_savepoint as only argument.

这是整个模块的代码:

module m_serialization

    implicit none

    type :: t_savepoint
        integer :: savepoint_index
        real    :: savepoint_value
    end type t_savepoint

    interface

        subroutine fs_initializesavepoint(savepoint)
            type(t_savepoint) :: savepoint
        end subroutine fs_initializesavepoint


    end interface

end module m_serialization

之所以想要这样一个接口,是因为以后我会让这个fortran模块与C互操作.

The reason why I want such an interface is that later on I will make this fortran module interoperate with C.

如果我尝试编译它 (gfortran-4.7.0),我会收到以下错误消息:

If I try to compile it (gfortran-4.7.0), I get the following error message:

            type(t_savepoint) :: savepoint
                                          1
Error: The type of 'savepoint' at (1) has not been declared within the interface

如果我在子程序中移动类型的定义,错误就会消失;但是如果我想在许多子程序中使用相同的类型,我应该在所有子程序中重复定义吗?

The error disappears if I move the definition of the type inside the subroutine; but if then I want to use the same type within many subroutines, should I repeat the definition in all of them?

提前谢谢你.

编辑:一种解决方案是将类型的定义移到另一个模块上,然后在每个子例程中使用它.不过我不太喜欢这个解决方案,因为类型 t_savepoint 和子例程是同一个概念主题的一部分.

EDIT: a solution would be to move the definition of the type onto another module and then to use it in every subroutine. However I don't like this solution too much, because the type t_savepoint and the subroutines are part of the same conceptual topic.

推荐答案

在一个接口块中是对还是错,您无法通过主机关联访问环境.要解决此问题,您需要显式导入数据类型:

Rightly or wrongly in an interface block you don't have access to the environment by host association. To fix this you need to import the datatype exlicitly:

[luser@cromer stackoverflow]$ cat type.f90
module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

  interface

     subroutine fs_initializesavepoint(savepoint)
       Import :: t_savepoint
       type(t_savepoint) :: savepoint
     end subroutine fs_initializesavepoint


  end interface

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

这是 f2003.

但是,我怀疑您提出此问题的方式表明您不会以最佳方式对其进行编码.更好的是将例程本身放在模块中.那么你根本不需要介意界面:

However I suspect the way you have put this suggests you are not going about coding this up the best way. Better is simply to put the routine itself in the module. Then you don't need bother with the interface at all:

module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

Contains

  Subroutine fs_initializesavepoint(savepoint)

    type(t_savepoint) :: savepoint 

    Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value

  End Subroutine fs_initializesavepoint

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

鉴于模块确实设计用于处理连接的实体,这确实是在 Fortran 中执行此操作的方式.它还具有只需要 f95 编译器的优点,因此是普遍可用的(尽管公认导入是通常实现的)

Given that modules are really designed to deal with connected entities this is really the way to do it in Fortran. It also has the advantage of only requiring a f95 compiler, so is universally available (though admittedly import is commonly implemented)

这篇关于如何在 Fortran 界面中使用用户定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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