【问题标题】:Fortran 'parameter' type not included in compiled objectFortran“参数”类型未包含在编译对象中
【发布时间】:2013-02-04 20:13:49
【问题描述】:

我有一个 Fortran 模块,其中包含一些具有 parameter 属性的变量和一些具有 save 属性的变量。 parameter 不包含在编译对象中,这在尝试组装库时会成为问题。例如,考虑一个文件testModule.f90

module testMOD
  integer, save :: thisIsSaved = 1
  integer, parameter :: thisIsParametered = 2
end module testMOD

我用:ifort -c testModule.f90 编译它。当我检查里面的东西时:

>$ nm testModule.o
0000000000000000 T testmod._
0000000000000000 D testmod_mp_thisissaved_

只有thisIsSaved 变量在那里。我知道我可以将thisIsParametered 更改为save 而不是parameter,但理想情况下,我想阻止链接用户更改此值。有没有办法做到这一点?

编辑:我希望 C 代码也可以访问这个库,而不仅仅是 Fortran。

【问题讨论】:

    标签: fortran static-libraries intel-fortran fortran-iso-c-binding


    【解决方案1】:

    这实际上应该存储在 .mod 文件中。所有的数据类型和函数原型都存储在那里,这就是为什么在向某人发送 .lib 文件时需要包含它的原因。在其他东西中使用后尝试在模块中链接,它应该可以正常工作。

    本质上 .mod 文件的用途与 c 中的 .h 文件相同,因此您当然必须将其包含在您的库中。

    [更新:] 如果您尝试在 C 中使用它,那么正如您所说,您无法轻松维护命名常量。作为替代方案,您可以在实体上使用受保护的属性。至少对于 Fortran,模块之外的任何内容都被限制写入变量。我不知道 C 编译器和链接器是否会尊重这种行为,但我认为这可能是你最好的选择。

    module testMOD
     INTEGER, PROTECTED, BIND(C)  :: globalvar = 1
    end module testMOD
    

    不幸的是,我并没有真正在与 C 的互操作性方面做太多事情,所以我不能真正保证 C 会尊重受保护的属性并且不允许更改变量。

    【讨论】:

    • 但是,如果从 C 代码访问该库,则它不使用 .mod 文件。
    • 确实如此。因此,您希望代码也被 c 编译器使用,并且仍然有可用的参数。我得考虑一下。当我想出它时,我会添加一些东西。
    • 您是否使用任何 2003 语言功能使其与 c 兼容?
    • 我在相关时使用 ISO_C_Binding。这实际上是需要链接到 C 和 Fortran 代码的大型代码库的一小部分。
    • protected 属性将其分配为一个变量,而parameter 是一个常量,但是虽然它是一个变量,但除了在该模块内之外不能更改空间。因此,如果您在该模块中使用子例程对其进行更改,则可以在该模块中对其进行修改。如果您在模块中有一些函数或子例程,甚至可能是一个类型方法,您也可以更改变量,只要在模块中声明和分配了类型。对于库的外部用户来说,区别在于它会出现在目标文件中,而 `parameter 不会。
    【解决方案2】:

    正如其他人所指出的,参数是一个命名常量,实现可能不会在目标代码中为该常量留出存储空间(特别是对于标量)。

    您的库应该为您的 C 客户端提供一个头文件。您可以通过 #define 或 const 在该头文件中定义 Fortran 参数的值。

    这需要在两个地方维护参数的值,但是您已经在库界面的其他方面承担了维护负担。

    【讨论】:

    • 我已经有了标题,但它们只有 extern "C" int testmod_mp_thisissaved_ 之类的东西。我想我可以修改我的 makefile 让它在头文件中填充这些值。
    • 对模块变量使用 BIND(C) 并直接指定它们的 C 名称。不要使用 Fortran 处理器的错误名称 - 这是可移植性和维护噩梦的秘诀。 ifort 的模块名称随着编译选项和编译器版本的变化而变化——更不用说转移到完全不同的处理器时可能发生的变化了。
    • 使用bind(C) 会影响 Fortran 代码与库的交互方式吗?
    • 对于变量 - 超出重新编译(属性将更改链接器使用的名称) - 否。对于过程 - 它们必须具有显式接口(注意模块过程自动具有显式接口)。对于这两种情况(过程和变量),BIND(C) 属性对声明/定义的事物施加了额外的要求(约束),但通常如果您希望某些东西可互操作,您已经满足了这些约束 - 例如F2008 处理器的配套 C 编译器不知道 Fortran 指针、可分配对象等。
    猜你喜欢
    • 2023-03-11
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多