如何为Fortran 95+模块库提供显式接口,并实现隐藏 [英] How to provide an explicit interface to a library of Fortran 95+ modules, with implementation hiding

查看:131
本文介绍了如何为Fortran 95+模块库提供显式接口,并实现隐藏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用gfortran的95+扩展。我有一个实用程序模块库,我想链接到其他项目,即作为库或共享对象/ DLL。但是,在Fortran中,我不明白如何将接口从Fortran实现中分离出来,而不需要维护模块接口的两个副本。

在C中,我会分开从执行的接口,如:

  api.h←包含←impl.h 
↑↑
包括包括
↑↑
user.c impl.c

有没有在现代Fortran中实现相同效果的方法?我需要为用户提供.mod文件的库吗?




  • 显式接口的单一定义
  • 仅接口定义暴露给用户代码



编辑:总结认为是)答案:


  • .mod文件是必需的,因为它们包含明确的接口定义


  • 模块没有标准的Fortran ABI - .mod文件是编译器特定的。

  • 对于实现隐藏问题,直接采用分析性的方法是在Fortran 2008中定义的子模块,而gfortran不支持。 避免使用模块,由@High-Performance-Mark和Fedora页面指出,将分发仅用于接口模块的包含文件以及用于实现的预编译.mods。
  • 使用包含了一些众所周知的令人讨厌的旅程,包括潜在的重新定义公共块。




  • 我有点惊讶,这里实际上并没有一个简单的答案。

    div>

    我相信您可以使用Fortran 2008编译器通过子模块执行此操作。来自FortranWiki:
    $ b


    子模块是Fortran 2008的一个特性,它允许模块过程使其接口在模块中定义,同时具有该程序在一个单独的单元中定义,一个子模块。

    Wikipedia (强调我的)


    [子模块允许]规范和实现一个模块可以用不同的程序单元表示,这样可以改进大型图书馆的封装,允许在发布权威接口的同时保留商业秘密,并且可以防止编译级联。


    我没有任何有关子模块的经验,但它们尚未得到广泛支持,但它们是需要注意的。



    编辑由于许多编译器不支持子模块,因此讨论其他选项。



    此页面询问类似的问题,并有一些不错的链接。在讨论Google网上论坛时特别有用(请参阅这篇文章)。总之,一个选择是:


    • 将所有库函数/子例程分组在一个文件中成为模块的一部分)。


    • 创建一个只包含您想要公开给最终用户的子例程接口的模块。

    • 为最终用户提供已编译的模块和库。然后,用户可以在他/她的程序中使用模块并链接到库。




    这允许你隐藏你不想暴露给最终用户的函数/子程序。



    从帖子中解除我链接到:


    有些编译器会生成一个.mod(或者编译器给它的任何名称)文件和一个库文件。 .mod文件具有符号;库文件包含模块中包含的可执行代码。在这种情况下,您必须将这两个文件分发给最终用户。另外,一些编译器(特别是f95)将符号和可执行代码放入一个.mod文件中。


    (最终!)编辑 Fedora wiki上有实用页面


    理想情况下,便携式Fortran库将避免使用模块。好消息是已经定义了子模块规范,这将允许模块的接口规范部分与程序源代码分开。在[c] e中,这是在Fortran编译器中实现的,它应该被所有打包的库使用。



    I'm using gfortran's 95+ extensions. I have a library of utility modules I'd like to link to other projects, i.e. as a library or shared object / dll. However, in Fortran, I don't understand how to split the interface from the implementation in Fortran without maintaining two copies of the module interface.

    In C, I would separate the interface from the implementation like:

     api.h ←includes← impl.h
       ↑                 ↑
    includes          includes
       ↑                 ↑
     user.c           impl.c
    

    Is there a way to achieve the same effects in modern Fortran? Do I need to provide users my library with the .mod files?

    • Single definition of an explicit interface
    • Only interface definitions are exposed to the user code

    Edit: To sum up (what I think is) the answer:

    • .mod files are needed, as they contain the explicit interface definition

    • There is no standard Fortran ABI for modules -- .mod files will be compiler-specific

    • The only directly analgous approach to the implementation-hiding problem is submodules, which are defined in Fortran 2008, and which gfortran does not support.

    • The most practical approach, aside from avoiding modules, noted by @High-Performance-Mark and the Fedora page, is to distribute include files for interface-only modules along with precompiled .mods for the implementation.

    • Using includes has some well-known and annoying trip-ups, including the potential redefinition of common blocks.

    I am a little surprised there is not actually a straightforward answer here.

    解决方案

    I believe that you can do this with submodules using Fortran 2008 compilers. From FortranWiki:

    Submodules are a feature of Fortran 2008 which allow a module procedure to have its interface defined in a module while having the body of the procedure defined in a separate unit, a submodule.

    From Wikipedia (emphasis mine)

    [Submodules allow] the specification and implementation of a module to be expressed in separate program units, which improves packaging of large libraries, allows preservation of trade secrets while publishing definitive interfaces, and prevents compilation cascades.

    I don't have any experience with submodules, and they are not widely supported yet, but they are something to be aware of.

    Edit Since many compilers don't support submodules, it is probably helpful to discuss other options.

    This page asks a similar question to this and has a number of nice links. Particularly useful in a discussion on Google Groups (see, in particular, this post). In summary, one option is to:

    • Group all the library functions/subroutines in a single file and by themselves (i.e. not being part of a module).

    • Create a module that only contains interfaces for those subroutines that you want to expose to the end user.

    • Provide end-users with the compiled module and the library. The user can then use the module in his/her programs and link against the library.

    This allows you to "hide" functions/subroutines that you don't want to expose to the end user.

    Lifted from the post I link to:

    Some compilers generate a .mod (or whatever name the compiler gives to it) file and a library file. The .mod file has the symbols; the library file contains the executable code included in the module. When this is the case, you must distribute both files to your end users.

    Also, some compilers (in particular f95) put the symbols and the executable code into a single .mod file. In this case, you only need to provide the .mod file to your end users.

    (final!) edit There is a useful page on the Fedora wiki:

    Ideally, portable Fortran libraries would avoid the use of modules. The good news is that a Sub-module specification has been defined which will allow the interface specification part of a module to be separate from the procedure source code. On[c]e this is implemented in Fortran compilers, it should be utilized by all packaged libraries.

    这篇关于如何为Fortran 95+模块库提供显式接口,并实现隐藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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