从Fortran调用的C函数中缺少参数

时间:2013-06-06 17:15:55

标签: c fortran fortran90 gfortran intel-fortran

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

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