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

2024-04-03

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

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

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

有没有办法在现代 Fortran 中达到同样的效果?我是否需要向用户提供我的库的 .mod 文件?

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

Edit:总结一下(我认为的)答案:

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

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

  • 解决实现隐藏问题的唯一直接类似的方法是子模块,它在 Fortran 2008 中定义,但 gfortran 不支持。

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

  • 使用包含会产生一些众所周知且烦人的错误,包括可能重新定义公共块。

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


我相信你可以做到这一点子模块 http://fortranwiki.org/fortran/show/Submodules使用 Fortran 2008 编译器。来自 Fortran 维基:

子模块是 Fortran 2008 的一项功能,它允许模块过程在模块中定义其接口,同时在单独的单元(子模块)中定义过程主体。

From 维基百科 http://en.wikipedia.org/wiki/Fortran(强调我的)

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

我对子模块没有任何经验,而且它们还没有得到广泛支持,但它们是需要注意的。

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

这一页 http://jblevins.org/log/library-distribution问了一个与此类似的问题,并且有许多不错的链接。在 Google 网上论坛的讨论中特别有用(特别参见,这个帖子 https://groups.google.com/d/msg/comp.lang.fortran/3mpu5fNgK9I/m-XL2mXIT3AJ)。总之,一种选择是:

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

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

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

这允许您“隐藏”您不想向最终用户公开的函数/子例程。

从我链接到的帖子中摘取:

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

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

(最终!)编辑有一个有用的页面 http://fedoraproject.org/wiki/PackagingDrafts/FortranLibraries在 Fedora 维基上:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为 Fortran 95+ 模块库提供显式接口,并隐藏实现 的相关文章

  • Intel Fortran 错误 #6633:实际参数的类型与虚拟参数的类型不同

    对于可能在这里提出这样一个基本问题 我深表歉意 我是使用英特尔 Fortran 编程的新手 所以我认为在这种情况下 我不知道有一些东西丢失或组织错误 如果有人能在这方面帮助我 我将不胜感激 问题是我在编译代码时看到以下错误 而我相信我已经声
  • 从接口访问参数 (Fortran)

    我正在使用参数来修复所用类型的精度 在我尝试在接口中使用相同类型之前 这种方法工作得很好 考虑这个小例子 module Hello implicit none save integer parameter K selected real k
  • f77 未格式化二进制文件的内容

    我有一个 f77 未格式化的二进制文件 我知道该文件包含 2 个浮点数和一个长整数以及数据 文件的大小为 536870940 字节 应包含 512 3 个浮点数据值以及 2 个浮点和长整数 512 3 个浮点数据值组成 536870912
  • 使用 MPI 派生数据类型

    我正在学习 Fortran 中的 BCASTing 数据类型 并且有一个代码可以从终端获取两个值并将它们显示在每个进程上 对于整数 整数和整数 实数类型的组合 value1 value2 这是有效的 但是对于整数 实数 8 的组合 它会失败
  • 使用 Iso_Fortran_Env 设置函数的 Kind 值

    如何使用 ISO Fortran Env 的内在函数以 Fortran 2008 惯用的方式设置函数的返回 KIND 值 通常在主程序中 我可以使用 ISO Fortran 内在函数 如下所示 program name here use i
  • 为什么我必须在 Fortran 中隐式指定函数的双精度返回值?

    我是 Fortran 新手 我正在尝试common堵塞 我的代码很简单 program main implicit double precision p real 8 x y common yvalue y x 3d0 y 3d0 prin
  • 忽略 doxygen 注释块中的行

    是否可以在 doxygen 注释块中包含将被 doxygen 忽略的内容 换句话说 我们可以在 doxygen 评论块中发表评论吗 背景 我们正在将 Fortran 项目的代码内注释转换为 doxygen 可解析的格式 但是该项目要求代码内
  • Fortran 读取混合字符串和数字数据

    我在读取语句时遇到问题 我更喜欢 Fortran90 尽管如果有帮助的话其他版本也是可能的 我的文件中有一堆数据行 可以描述为 以空格分隔 没有固定的格式 包含一个字符串 后跟 7 个数字 字符串包含正斜杠 这是一个例子 maxele OS
  • 在 Fortran 中确定循环后循环控制变量的值

    我有以下程序 program example implicit none integer i x1 real x 10 0 do i 10 1 2 x 10 i 2 i 1 enddo x1 i 2 1 end program exampl
  • 链接到遗留库:-lgfortranbegin from a premade makefile

    我在尝试编译由一些研究人员开发的程序时遇到了一些麻烦 该程序应该以非常精确的方式计算傅立叶变换和其他一些有用的操作科学论文在这里 https www researchgate net profile Gerard Gomez2 public
  • 将 C 字符串数组传递给 Fortran (iso_c_binding)

    如何传递 C 字符串数组 char cstrings 到 Fortran 子程序 问题使用 iso c binding 的 fortran C 桥接器中的字符串数组 https stackoverflow com questions 968
  • Fortran 03/08(gfortran 编译器)中使用无限多态类型进行数组操作

    我想通过以下方式实现有用的数组操作 添加元素 删除元素 通过可分配 指针 二叉树结构实现不同的实现 class 特征 无限多态性 我使用 gfortran 5 0 应该可以处理这样的功能 我需要它 以免为我使用的每种类型重复相同的代码 这应
  • Fortran 函数:指针作为实际参数,目标作为形式

    我正在尝试破译 Fortran 代码 它将指向函数的指针作为实际参数传递 而形式参数则是目标 它在主程序中定义并分配一个 globalDATA 类型的指针 然后调用一个传递该指针的函数 module dataGLOBAL type glob
  • 将数组从 .npy 文件读入 Fortran 90

    我使用 Python 以二维数组 例如 X 的形式生成一些初始数据 然后使用 Fortran 对它们进行一些计算 最初 当数组大小约为 10 000 x 10 000 时 np savetxt 在速度方面表现良好 但是一旦我开始增加数组的维
  • 尝试读取名单后返回的状态不是预期的

    我想从文件中读取名单 但在名单不存在的情况下实现捕获选项 从我读到的here http msg ucsf edu local programs IBM Compilers Fortran html pgs lr76 htm我期望状态为 84
  • f951 错误:无法识别的命令行选项

    我在linux上 正在编译以下内容 mpif90 shared source F90 object1 o object2 o L some path Qoption link rpath some path I some path lhdf
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints
  • 使用 MacLaurin 展开的 Fortran Sine 函数的微小差异

    我正在用 Fortran 创建一个程序 它接受以弧度表示的 sin x 的 x 然后是要计算的项数 这是我的程序 Sine value using MacLaurin series program SineApprox implicit n
  • 有没有一种简单的方法来准备 Fortran 代码以进行并行调用

    我想使用 OpenMP 在 C 程序中并行求解多个大型 ODE 系统 由于某些原因 我需要使用 ODE 求解器 但我只能找到 Fortran 90 子例程 而且代码太大 无法简单地将其转换为 C 我知道 Fortran 广泛使用静态内存 因
  • Fortran gfortran linux 中的“分段错误(核心转储)”错误

    我正在创建一个程序 该程序将分析目录中的文件 fits 然后它将在另一个目录中创建另一个文件 txt 它只是一个转换器 当我尝试执行该程序 编译正常 时 它给了我一条错误消息 程序收到信号 SIGSEGV 分段错误 无效的内存引用 此错误的

随机推荐

  • 一次上传两个文件

    我正在尝试使用 codeigniters 上传类一次上传两个文件 两个文件字段 尽管提供了字段名称 codeigniter 仍会在第二个字段上产生错误 这是 codeigniter php 或 html 的限制 还是我只是错误地使用了该类
  • $concat mongodb 中的两个字段

    我有这两个集合 employees id NumberInt 0 name Max surname Power and loggableUser id NumberInt 0 employee NumberInt 1 现在我必须在以下查询中
  • 如何以递归方式将 React 组件渲染到自身中

    我有一个组件 即列表组件 列表组件可以渲染项目 通过组件ListItem 通过下面的内容可以轻松实现 import React from react import ListItem from list item list item clas
  • 如何使用 FastAPI 防止表单输入时页面重新加载

    我有一个使用 FastAPI 的简单程序 它将浮点值乘以 2 并将其显示在 HTML 中 该值通过 HTML 表单输入 我想知道如何获得动态显示的值 而无需在按 Enter 或按提交按钮时重新加载页面 以下是脚本 main py 和 dou
  • 在 C# 中用点和小数格式化数字[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我需要先 点 然后逗号 例如 1234567 这是一个数字或金钱的示例 我想要像 1 234 567 00 谁能给我答案 如果执行代码的计算
  • Gcc 卸载编译选项

    我正在尝试使用 Ubuntu 18 04 上的 gcc 10 CUDA 11 和此 CMakeLists txt 文件 或 OpenMP 版本 构建最简单的具有 GPU 卸载功能的 OpenMP 或 OpenACC C 程序 cmake m
  • 下载的php总是损坏

    我有一个用 PHP 编写的下载脚本 我的视图文件脚本链接到 ids 然后选择与该 ID 匹配的所有数据 然后使用该数据下载照片 我的照片在文件夹中重要吗 它被移动到一个文件夹 然后该目录被上传到MYSQL数据库 目前的代码现在允许一些文件完
  • Python3,与列表重新匹配

    我读到了这个 https stackoverflow com a 17090205 6426449 https stackoverflow com a 17090205 6426449 我制作了一个不能在 django 中的用户名上使用的列
  • 在 WSL (Ubuntu) 中安装适用于 python3 的 venv

    我正在尝试配置venv在带有 Ubuntu 的 Linux 的 Windows 子系统上 我尝试过的 1 安装venv通过pip pip3 准确地说 pip3 install venv 我收到以下错误 ERROR Could not fin
  • 我应该如何在 PHP 中实现延迟会话创建?

    默认情况下 PHP 的会话处理机制会设置会话 cookie 标头并存储会话 即使会话中没有数据也是如此 如果会话中没有设置数据 那么我不想要Set Cookie在响应中发送到客户端的标头 我不希望在服务器上存储空会话记录 如果数据添加到 S
  • 表达式 > 作为属性

    我正在尝试重构通用存储库的一些代码 该存储库传入一个过滤器对象 该过滤器对象将过滤数据以及页面 排序等 各传承Filter 例如 CustomerFilter 可以选择定义自己的表达式过滤器 该过滤器将由存储库中的基类应用 因此客户过滤器将
  • 如何在 Hibernate 中进行基于自定义查询的集合映射?

    我有一个对象被映射为一组对象 非常简单 然而 我真正想做的是为该映射设置一些标准 这是当前的映射
  • 尝试在空对象引用上调用虚拟方法“int java.lang.String.length()”[重复]

    这个问题在这里已经有答案了 所以我有带有选项卡的 Android 应用程序RecyclerView 当我运行我的应用程序时 它崩溃了 logcat java lang NullPointerException Attempt to invo
  • 将网站部署到 Azure 和传统 IIS

    我目前使用旧版 ASP NET Web 应用程序 未来的要求之一是它可以部署到 Windows Azure 我想知道管理 Azure 和传统 IIS Web 服务器的部署有多困难 Azure 似乎需要 Web 应用程序项目的特定自定义版本
  • 来自代码的队列 Azure DevOps YAML 管道不接受运行时参数

    YAML 管道如下所示 parameters name parameter1 type string steps task PowerShell 2 inputs targetType inline script Write your Po
  • PHP 解析错误:语法错误,意外的 ':',期望 ';'或者 '{'

    我正在尝试玩 php7 我已经安装了https github com rlerdorf php7dev https github com rlerdorf php7dev并通过phpstorm连接 我正在尝试使用这样的新功能
  • 红宝石在线救援

    我最近了解到你可以使用rescue在一行代码上 以防该行出现问题 请参阅http www rubyinside com 21 ruby tricks 902 html http www rubyinside com 21 ruby tric
  • CurrentValueSubject 和 @Published 之间的区别

    所以我正在深入研究联合收割机 并且出现了这个问题 使用之间有什么真正的区别吗CurrentValueSubject 并使用设置其值currentValueSubject value 或使用 Published var并通过以下方式访问其发布
  • 获取调试端口时出错 :: 无法使用当前安全信息在 RDS 服务器上进行身份验证。 (Adobe 的 ColdFusion 扩展)

    我安装了 我添加了本地服务器 127 0 0 1 80 创建了工作区 现在我想调试我的项目 我打开了一些 cfml 文件 进入 运行和调试 选项卡 然后单击 运行和调试 按钮 我收到以下错误消息 调试器已停止 获取调试端口时出错 无法使用当
  • 如何为 Fortran 95+ 模块库提供显式接口,并隐藏实现

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