使用 GCC 对模块内的 fortran 子例程进行外部命名
Posted
技术标签:
【中文标题】使用 GCC 对模块内的 fortran 子例程进行外部命名【英文标题】:External naming of fortran subroutine inside a module using GCC 【发布时间】:2018-06-22 14:11:21 【问题描述】:我的目标是重命名模块内的 fortran 子例程,使其易于被 C 代码调用(即不带 __<modulename>_MOD_
前缀),并使用 GCC-6.3.0。我不能使用bind(c,name='')
,即使它很好用。我读过我应该使用界面,但没有任何成功。这是 MWE:
module testmodule
interface
subroutine func02
!GCC$ ATTRIBUTES CDECL :: func01
end subroutine
end interface
contains
subroutine func01
print*,"func01"
end subroutine
end module
我使用命令gfortran -c test.f90
进行编译,然后使用nm test.o
检查子例程是否正确重命名,但没有func02
的迹象。
任何帮助表示赞赏。
【问题讨论】:
您是否尝试过使用 DLLEXPORT 属性? 为什么不能使用bind(c)
?任何阻止您使用的东西也可能阻止您使用任何其他建议,因此您澄清一下会很有用。
@RodrigoRodrigues DLLEXPORT 也不起作用。我也在Linux上工作。 @francescalus 超过 10000 行代码具有很高的复杂性,使用 bind(c)
改变了许多从 c 结构开始的东西,这些东西从 C 传输到 Fortran 非常不同(使用 void *
)。我需要这个特定的 MWE 才能工作。感谢您对这个问题的兴趣。
如果 BIND(C) 对您的程序的性质进行了一些重要的更改,那么您的示例需要包含这些更改,以便我们可以为您提供适当的建议。如果您有现有的 C 代码调用现有的 Fortran 过程,但有一个很长有趣的 MOD 名称,那么构造 BIND(C) 包装器应该是相当直接的(您不必更改原始 Fortran - 您可以添加另一个过程作为中间过程)为保持二进制兼容性的现有过程,禁止名称。
【参考方案1】:
您可以使用 BIND(C) 重命名子程序。无论您读到什么关于 INTERFACE
的内容似乎都是在转移注意力。
module testmodule
contains
subroutine func01() bind(c, name='func2')
print*,"func01"
end subroutine
end module
使用简单的命令“gfortran -c a.f90”,我看到以下结果
nm a.o
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character_write
00000000 T func2
【讨论】:
对不起,我已经解释过 bind(c) 对我来说是禁止的。我同意你的代码有效,但它不适合我。 @ThomasGuenet,你是什么意思禁止? 我无法使用它,因为复杂的 fortran 代码结构意味着更改太多代码。因此bind(c)
是任何人开始新项目的解决方案,但我要求另一种解决方案:这是这个问题的目的。
您可以在一个地方使用bind(c)
来生成正确的绑定名称,而不是在其他任何地方使用它。我不明白bind(c)
会如何对您的代码库的其余部分造成任何问题。
@evets,这不是不可能的。 ThomasGuenet,您可以使用 gfortran 生成程序集文件。通过 sed 提供该文件以去除前缀。然后使用 gfortran 编译 sed 编辑的程序集。祝你好运,或者使用 BIND(C)。以上是关于使用 GCC 对模块内的 fortran 子例程进行外部命名的主要内容,如果未能解决你的问题,请参考以下文章