How to provide an explicit interface to a library of Fortran 95+ modules, with implementation hiding

十年热恋 提交于 2019-12-05 15:46:33

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.

Another approach to separating interface from implementation and for writing each only once, an approach that has been much used since FORTRAN77 (and possibly even before then) is to use an INCLUDE line to include the text of one source file into another source file. There are a lot of sound software engineering reasons for avoiding INCLUDEs, and a lot of practical utility in making use of them.

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

It depends on what you want to do. If the intent is to hide the code from people because of trade secrets, the you could write "interfaces" and provide pre-compiled libraries rather than actual code. The user would compile the files with the interfaces to be able to call your procedures.

If you just want to practice good programming practices of exposing only what is necessary you could use modules and specify some procedures or module variables to be internal to the modules by designating them to be "private". A person can see the code with an editor but the procedures won't be callable outside of the module. You can only disclose to the rest of the program the procedures that are supposed to be used and hide the others. You can make "private" the default with a private statement at the top of the module and the specify the procedures that need to be visible on a "public" statement.

Unless you don't want your users to see or to compile your source code, I wouldn't supply .mod files. That creates the problem of supporting various compilers instead of simply supply the source code. The "private" and "public" statements should achieve your two goals of not duplicating interface definitions and only exposing the interfaces that you wish to exposure. Unless your program is very large or there are other issues the other approaches seem overly complicated to me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!