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

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

问题描述

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



这是整个模块的代码:

  module m_serialization 

隐式无

类型:: t_savepoint
integer :: savepoint_index
real :: savepoint_value
结束类型t_savepoint

接口

子程序fs_initializesavepoint(savepoint)
类型(t_savepoint)::保存点
结束子程序fs_initializesavepoint


结束接口

结束模块m_serialization
$ b $ p
$ b

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



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

  type(t_savepoint):: savepoint 
1
错误:(1)处的'savepoint'类型尚未在接口中声明

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



预先感谢您。



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

解决方案

在接口块中正确或错误地通过主机关联无法访问环境。为了解决这个问题,你需要显式地导入数据类型:

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

隐含无

类型:: t_savepoint
整数:: savepoint_index
real :: savepoint_value
结束类型t_savepoint

接口

子程序fs_initializesavepoint(保存点)
导入:: t_savepoint
类型(t_savepoint)::保存点
结束子程序fs_initializesavepoint


结束接口

结束模块m_序列化
[luser @ cromer stackoverflow] $ gfortran -c type.f90

这是f2003。



然而,我怀疑你这样做的方式表明你不会去编码这最好的方式。更好的做法是把例程本身放在模块中。那么你根本不需要打扰界面:

  module m_serialization 

隐式无

类型:t_savepoint
整数:: savepoint_index
real :: savepoint_value
结束类型t_savepoint

包含

子程序fs_initializesavepoint(保存点)

类型(t_savepoint)::保存点

写入(*,*)保存点%保存点索引,保存点%保存点值

结束子程序fs_initializesavepoint

结束模块m_序列化
[luser @ cromer stackoverflow] $ gfortran -c type.f90

考虑到模块真的是设计用于处理连接的实体,这实际上是在Fortran中实现的方式。它还具有只需要f95编译器的优点,因此可以普遍使用(尽管通常会实现导入)


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.

Here is the code for the whole module:

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

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

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?

Thank you in advance.

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

This is 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

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天全站免登陆