如何为Fortran 95+模块库提供显式接口,实现隐藏

gib*_*bss 4 fortran gfortran fortran95

我正在使用gfortran的95+扩展.我有一个实用程序模块库,我想链接到其他项目,即作为库或共享对象/ DLL.但是,在Fortran中,我不明白如何在不保留模块接口的两个副本的情况下将接口与Fortran中的实现分开.

在C中,我将接口与实现分开,如:

 api.h ?includes? impl.h
   ?                 ?
includes          includes
   ?                 ?
 user.c           impl.c
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 需要.mod文件,因为它们包含显式接口定义

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

  • 实现隐藏问题的唯一直接分析方法是子模块,它在Fortran 2008中定义,并且gfortran不支持.

  • 除了避免使用模块之外,@ High-Performance-Mark和Fedora页面提供的最实用的方法是分发仅用于接口的模块的包含文件以及用于实现的预编译.mods.

  • 使用包含一些众所周知和烦人的旅行,包括潜在的重新定义公共块.

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

Chr*_*ris 5

我相信您可以使用Fortran 2008编译器对子模块执行此操作.来自FortranWiki:

子模块是Fortran 2008的一个特性,它允许模块过程在模块中定义其接口,同时在单独的单元(子模块)中定义过程的主体.

来自维基百科(强调我的)

[子模块允许]模块的规范和实现以单独的程序单元表示,这改进了大型库的包装,允许在发布确定的接口时保留商业机密,并防止编译级联.

我对子模块没有任何经验,但它们还没有被广泛支持,但它们是值得注意的.

编辑由于许多编译器不支持子模块,因此讨论其他选项可能会有所帮助.

此页面提出了类似的问题,并提供了许多不错的链接.在Google网上论坛的讨论中特别有用(特别参见本文).总之,一种选择是:

  • 将所有库函数/子例程分组到一个文件中并单独(即不是模块的一部分).

  • 创建一个模块,该模块仅包含要向最终用户公开的子例程的接口.

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

这允许您"隐藏"您不希望向最终用户公开的函数/子例程.

从帖子中解脱我链接到:

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

此外,一些编译器(特别是f95)将符号和可执行代码放入单个.mod文件中.在这种情况下,您只需要向最终用户提供.mod文件.

(最后!)编辑 Fedora wiki上有一个有用的页面:

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