我正在使用调用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位于第一个空白参数后面的逗号处.我找不到任何关于这里发生了什么的信息.这是用于传递伪参数的英特尔编译器特定语法吗?如果是这样,有人可以指点我参考吗?
最佳答案 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