4

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

4

1 回答 1

2

Ifort actually passes the NULL pointer for the not specified arguments. Compiling and linking the Fortran program

program test
  implicit none

  call c_func(1, ,3)

end program test

and the corresponding C-function

#include <stdio.h>

void c_func_(void *p1, void *p2, void *p3)
{
  printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}

you would obtain:

P1: 0x4729f4
P2: (nil)
P3: 0x4729f0

This behaviour is, however, definitely an extension to the standard. By giving the C function an explicit interface in Fortran, you can "emulate" it with any compilers, implementing the C-binding features of the Fortran 2003 standard. You would have to pass the C_NULL_PTR constant for the given parameter.

In the Fortran program below, I created an explicit interface for the C-function. In that example Fortran would pass a pointer to an integer, an arbitrary C-pointer and again a pointer to an integer.

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

Since I used an explicit name in the bind(c) option, the name of the function in the C-code does not need to contain any magic, compiler dependent trailing underscores any more. I also changed the pointer types on the C-side to the corresponding types:

#include <stdio.h>

void c_func(int *p1, void *p2, int *p3)
{
  printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}

Compiling and linking the two componentes with gfortran (I used 4.7.2) and executing the resulting binary results in:

P1: 0x400804
P2: (nil)
P3: 0x400800
于 2013-06-06T20:34:39.633 回答