“我怎么能?”;转口;一个现有的绑定(C)函数,在Fortran模块中重载,名为ifort?
在我尝试使用ifort之前,我对使用gfortran的构造非常满意。虽然我从来没有看过清楚的记录。我只是试了一下,效果不错。我很好奇,我如何调整下面的示例,使ifort 11.1可以咀嚼它“我怎么能?”;转口;一个现有的绑定(C)函数,在Fortran模块中重载,名为ifort?,fortran,intel-fortran,fortran-iso-c-binding,Fortran,Intel Fortran,Fortran Iso C Binding,在我尝试使用ifort之前,我对使用gfortran的构造非常满意。虽然我从来没有看过清楚的记录。我只是试了一下,效果不错。我很好奇,我如何调整下面的示例,使ifort 11.1可以咀嚼它 module A use iso_c_binding implicit none interface function foo(x) bind(C, name="strlen") use, intrinsic :: iso_c_binding charact
module A
use iso_c_binding
implicit none
interface
function foo(x) bind(C, name="strlen")
use, intrinsic :: iso_c_binding
character(c_char), intent(in) :: x
integer(c_size_t) :: foo
end function foo
end interface
end module A
module B
use A
! use A, foo0 => foo
implicit none
interface foo
module procedure foo1
procedure foo
end interface foo
contains
function foo1(x)
real, intent(in) :: x
real :: foo1
foo1 = 2. * x
end function foo1
end module B
program C
use B
implicit none
write (*,*) foo(C_CHAR_"Hello" // C_NULL_CHAR)
write (*,*) foo(2.)
end program C
这是我收到的一条错误消息
tst.f90(20): error #6643: This statement is incorrectly positioned.
procedure foo0
-----^
tst.f90(20): error #8168: Parentheses are required after the PROCEDURE keyword.
procedure foo0
-----^
它是GNU扩展吗<代码>-学究式的不会抱怨。它按我的预期工作
5
4.00000000
我是否必须在接口foo中写入完整的foo0声明细节
更新2013-03-31
我调整了上面的示例代码,以包括bind(C)
。由于它驻留在接口中
,因此即使使用gfortran,我也无法使用模块
。很抱歉,我之前用了不恰当的精简示例来误导您
另一次更新2013-03-31
显然,ifort版本13.1.1
不支持这种构造(无论我是否将foo重命名为foo0)
如果在程序之前添加模块
,则
tst.f90(22): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure. [FOO]
module procedure foo
----------------------^
除非我在所有细节中再次明确声明bind(C)接口,否则目前似乎无法实现我想要的功能:(这是Fortran 2003的一项功能: 指定模块时,过程名列表只能包含模块过程。未指定模块时,过程名列表可以包含过程指针、外部过程、伪过程或模块过程 您的版本11.1已经过时,当前版本是13,但我不确定现在是否支持它 在这种情况下,可以使用
模块过程
,直到您的编译器版本完全支持Fortran 2003:
如果出现MODULE关键字,则每个过程名称必须是模块过程,并且必须在当前范围内可访问
来源:使用
foo
C函数,似乎foo
不能作为模块过程。中间函数可以用作解决方法:
module A
use, intrinsic :: iso_c_binding
implicit none
interface
function strlen(x) bind(C, name="strlen")
use, intrinsic :: iso_c_binding
character(kind=c_char, len=1), dimension (*), intent(in) :: x
integer(c_size_t) :: strlen
end function strlen
end interface
contains
function foo (x)
character(kind=c_char, len=*), intent(in) :: x
integer (c_size_t) :: foo
foo = strlen (x)
end function foo
end module A
module B
use A
! use A, foo0 => foo
implicit none
interface foo
module procedure foo1
module procedure foo
end interface foo
contains
function foo1(x)
real, intent(in) :: x
real :: foo1
foo1 = 2. * x
end function foo1
end module B
program C
use B
implicit none
write (*,*) foo(C_CHAR_"Hello" // C_NULL_CHAR)
write (*,*) foo(2.)
end program C
在模块B中,use语句中的重命名列表是不必要的。您只需在通用接口块中编写
过程foo
,它将引用模块A中的函数foo。@m-s-B确实,我给出的示例适用于模块
。但是它是一个简化版本。在我的示例中,foo0作为绑定(C).我在(1)处遇到一个类似于
error的错误:“foo0”不是模块过程`@eriktous我记不起为什么我首先重命名了它。也许它被其他错误掩盖了,我决定存在名称冲突,例如,用相同的名称命名类型和模块。我更新了示例代码,显示了为什么我不能使用模块过程
。如果它在标准中,并且在某个point将迎头赶上,这对我来说很好。我将尝试更新的ifort版本。由于我生成Fortran代码,我最终将绑定(c)声明放在通用接口中,而不是依赖编译器对其进行优化。
module A
use, intrinsic :: iso_c_binding
implicit none
interface
function strlen(x) bind(C, name="strlen")
use, intrinsic :: iso_c_binding
character(kind=c_char, len=1), dimension (*), intent(in) :: x
integer(c_size_t) :: strlen
end function strlen
end interface
contains
function foo (x)
character(kind=c_char, len=*), intent(in) :: x
integer (c_size_t) :: foo
foo = strlen (x)
end function foo
end module A
module B
use A
! use A, foo0 => foo
implicit none
interface foo
module procedure foo1
module procedure foo
end interface foo
contains
function foo1(x)
real, intent(in) :: x
real :: foo1
foo1 = 2. * x
end function foo1
end module B
program C
use B
implicit none
write (*,*) foo(C_CHAR_"Hello" // C_NULL_CHAR)
write (*,*) foo(2.)
end program C