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 は最初のブランク引数に続くコンマにあります。ここで何が起こっているのかについての情報が見つかりません。これは、仮引数を渡すための Intel コンパイラ固有の構文ですか? もしそうなら、誰かが私に参考文献を教えてもらえますか?

4

1 に答える 1

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);
}

2 つのコンポーネントを gfortran (私は 4.7.2 を使用) でコンパイルおよびリンクし、結果のバイナリを実行すると、次のようになります。

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