我正在使用调用C函数的Fortran 90代码。此代码经过充分测试,可以与英特尔Fortran编译器成功编译。我试图让它与GNU Fortran编译器一起工作。 F90代码调用C函数,但它没有指定一些参数。电话看起来像这样:
call c_func_name(1, n, q, , , , p)
显然可以正常使用ifort,但不适用于gfortran,它会因错误而失败
Error: Syntax error in argument list at (1)
其中1位于第一个空白参数后面的逗号处。我找不到任何关于这里发生了什么的信息。这是用于传递伪参数的英特尔编译器特定语法吗?如果是这样,有人可以指点我参考吗?
答案 0 :(得分:2)
Ifort实际上传递了未指定参数的NULL指针。编译和链接Fortran程序
program test
implicit none
call c_func(1, ,3)
end program test
和相应的C函数
#include <stdio.h>
void c_func_(void *p1, void *p2, void *p3)
{
printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}
你会得到:
P1: 0x4729f4
P2: (nil)
P3: 0x4729f0
然而,这种行为绝对是标准的延伸。通过在Fortran中为C函数提供一个显式接口,您可以使用任何编译器“模拟”它,实现Fortran 2003标准的C绑定功能。您必须为给定参数传递C_NULL_PTR
常量。
在下面的Fortran程序中,我为C函数创建了一个显式接口。在该示例中,Fortran将传递指向整数的指针,任意C指针以及指向整数的指针。
program test
use iso_c_binding
implicit none
interface
subroutine c_func(p1, p2, p3) bind(c, name='c_func')
import
integer(c_int) :: p1
type(c_ptr), value :: p2
integer(c_int) :: p3
end subroutine c_func
end interface
type(c_ptr) :: cptr
call c_func(1, C_NULL_PTR, 3)
end program test
由于我在bind(c)
选项中使用了显式名称,因此C代码中函数的名称不再需要包含任何魔术,编译器相关的尾随下划线。我还将C端的指针类型更改为相应的类型:
#include <stdio.h>
void c_func(int *p1, void *p2, int *p3)
{
printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}
使用gfortran(我使用4.7.2)编译和链接两个组件并执行生成的二进制结果:
P1: 0x400804
P2: (nil)
P3: 0x400800