How to provide an explicit interface for the Fortran 95+ module library, while hiding the implementation

I am using gfortran 95+ extensions. I have a library of utility modules that I would like to link to other projects, that is, as a library or a shared object / dll. However, in Fortran, I don’t understand how to separate the interface from the implementation in Fortran without supporting two copies of the module interface.

In C, I would extract the interface from the implementation, for example:

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

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

  • Unified Definition of an Explicit Interface
  • Only interface descriptions are displayed in user code.

Edit: To summarize (what I think):

  • .mod files are needed because they contain an explicit interface definition

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

  • The only direct analogue of the approach to hiding the implementation is the submodules that are defined in Fortran 2008 and which gfortran does not support.

  • The most practical approach, in addition to excluding the modules noted on the @ High-Performance-Mark and Fedora pages, is to distribute include files for modules with an interface, as well as precompiled .mods for implementation.

  • Usage includes some well-known and annoying outages, including the possible redefinition of common blocks.

I'm a little surprised that there really is no direct answer here.

+4
source share
3 answers

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

Submodules are a function of Fortran 2008 that allows a modular procedure to have its own interface defined in a module, having the body of a procedure defined in a separate module, a submodule.

From Wikipedia (highlighted by me)

[Submodules allow] the specification and implementation of the module, which should be expressed in separate program units, which improves the packaging of large libraries, allows you to keep trade secrets when publishing the final interfaces and prevents compilation cascades.

I have no experience with submodules, and they have not yet become widespread, but they should know.

Change Since many compilers do not support submodules, it is probably useful to discuss other options.

This page asks a similar question and has some good links. Especially useful when discussing Google groups (see, in particular, this post ). Thus, one of the options:

  • Group all library functions / routines in a single file and on their own (i.e. not being part of a module).

  • Create a module that contains only interfaces for the routines that you want to provide to the end user.

  • Provide the compiled module and library to end users. The user can then use module in their programs and contact the library.

This allows you to β€œhide” functions / routines that you do not want to provide to the end user.

Sent from a post, I refer to:

Some compilers generate a .mod file (or any other name provided to it by the compiler) and a library file. The .mod file has characters; the library file contains executable code included in the module. In this case, you should distribute both files to your end users.

In addition, some compilers (particularly f95) put characters and executable code into a single .mod file. In this case, you only need to provide the .mod file for your end users.

(final!) edit The Fedora wiki has a useful page :

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

+5
source

Another approach to separating the interface from the implementation and for writing only once - an approach that has been very used with FORTRAN77 (and perhaps even before), is to use the INCLUDE line to include the text of one source file in another source file. There are many fundamental software specifications for avoiding INCLUDE and many practical utility in using them.

I must add that I like the approaches that Chris has already outlined better than resorting to INCLUDE, but sometimes needs should ...

+2
source

It depends on what you want to do. If the goal is to hide the code from people because of trade secrets, you can write β€œinterfaces” and provide pre-compiled libraries, not the actual code. The user must compile the files with the interfaces in order to be able to call your procedures.

If you just want to practice good programming methods, revealing only what is needed, you can use modules and specify some procedures or module variables to be internal to the modules, denoting them as "private". A person can see the code using the editor, but the procedures will not be called outside the module. You can disclose the rest of the program procedures that should be used, and hide others. You can make "private" by default with a closed statement at the top of the module and specify the procedures that should be visible in the "public" statement.

If you do not want your users to see or compile the source code, I would not supply .mod files. This creates the problem of supporting various compilers instead of simply providing the source code. The private and public statements must achieve two goals: not to duplicate interface definitions and expose only the interfaces you want to expose. If your program is not very large or there are other problems, other approaches seem to me too complicated.

+2
source

Source: https://habr.com/ru/post/1415365/


All Articles