ナビゲーション:前へ 上へ 次へ
11.8 高度なC相互運用性
-
[7.0]
組込みモジュール
ISO_C_BINDING
のC_FUNLOC
関数は、相互運用不可能な手続き引数を受け入れます。 生成されたC_FUNPTR
値は、C関数ポインターに変換しないでください。 ただし、ISO_C_BINDING
のC_F_PROCPOINTER
サブルーチンを使用して、適切な(相互運用不可能な)Fortran手続きポインターに変換できます。
例)USE ISO_C_BINDING ABSTRACT INTERFACE SUBROUTINE my_callback_interface(arg) CLASS(*) arg END SUBROUTINE END INTERFACE TYPE,BIND(C) :: mycallback TYPE(C_FUNPTR) :: callback END TYPE ... TYPE(mycallback) cb PROCEDURE(my_callback_interface),EXTERNAL :: sub cb%callback = C_FUNLOC(sub) ... PROCEDURE(my_callback_interface),POINTER :: pp CALL C_F_PROCPOINTER(cb%callback,pp) CALL pp(...)
この機能は、C_FUNPTR値がCコードによって操作されるデータ構造に格納されている場合に、混合言語プログラムで役立つ場合があります。
-
[7.0]
組込みモジュール
ISO_C_BINDING
のC_LOC
関数は、 相互運用不可能な型の配列を受け入れ、C_F_POINTER
関数は、相互運用不可能な型の配列ポインターを受け入れます。 配列は、非多相で連続している必要があります。これによりプログラムがCルーチンまたはCデータ構造を介して相互運用不可能な配列の不透明な“handle”を渡し、 後にFortran配列ポインターを再構築できるようにします。この事は混合言語のCおよびFortranプログラミングとの相互運用性が向上させます。 この種の使用法は、以前はスカラでのみ可能でした。
-
[7.2]
名前付き定数
C_PTRDIFF_T
が組込みモジュールISO_C_BINDING
に追加されました。 これは C の型ptrdiff_t
に対応する整数の種別であり、二つのポインタ間の差を保持するのに十分な大きさの整数です。 例えば、以下の引用仕様Interface Function diff_cptr(a,b) Bind(C) Use Iso_C_Binding Type(C_ptr),Value :: a, b Integer(C_ptrdiff_t) diff_cptr End Function End Interface
は C 関数と相互運用しますptrdiff_t diff_cptr(void *a,void *b) { return a - b; }
-
[7.2]
組込みモジュール
ISO_C_BINDING
では、手続きC_LOC
とC_FUNLOC
は 純粋手続とみなされ、C_F_POINTER
とC_F_PROCPOINTER
は 非純粋手続とみなされます。 純粋手続き内で使用される場合、C_FUNLOC
の引数もまた 純粋手続きでなければなりません。 -
[7.1]
次元数引継ぎ変数は、
ALLOCATABLE
またはPOINTER
属性を持つものであっても、BIND(C)
ルーチンの仮引数として許可されます。 次元数引継ぎの引数は、“C記述子”として参照によって渡されます。 それが何を意味するかをデコードするのはCルーチン次第です。 C記述子は、それを操作するためのいくつかのユーティリティ関数とともに、 ソースファイルISO_Fortran_binding.h
に定義されています。 このファイルはコンパイラのライブラリディレクトリにあります(Linuxでは通常/usr/local/lib/nAG_Fortran
、ただし、インストール時に変更可能)。このトピックは非常に複雑であり、このドキュメントの範囲を超えています。 読者は、Fortran2018標準または優れた教科書をご参照下さい。
-
[7.1]
TYPE(*)
(“型引継ぎ”)仮引数は、BIND(C)
手続きで許可されます。 “void*
”として宣言されたC引数と相互運用します。 C側ではスカラと大きさ引継ぎに違いはありませんが、Fortran側では、仮引数がスカラの場合、実際の引数もスカラでなければなりません。 仮引数が配列の場合、実際の引数も配列でなければなりません。実引数は仮引数
TYPE(*)
に直接渡すことができるため、C_LOC
関数は不要であり、実引数にTARGET
属性は必要ありません。例)
Program type_star_example Interface Function checksum(scalar,size) Bind(C) Use Iso_C_Binding Type(*) scalar Integer(C_int),Value :: size Integer(C_int) checksum End Function End Interface Type myvec3 Double Precision v(3) End Type Type(myvec3) x Call Random_Number(x%v) Print *,checksum(x,Storage_Size(x)/8) End Program int checksum(void *a,int n) { int i; int res = 0; unsigned char *p = a; for (i=0; i<n; i++) res = 0x3fffffff&((res<<1) + p[i]); return res; }
-
BIND(C)
手続きには、省略可能な引数を指定できます。 このような引数はVALUE
属性を持つこともできません。BIND(C)
手続きに省略可能な引数を指定しない場合は、nullポインタを渡すことができます。例)
Program optional_example Use Iso_C_Binding Interface Function f(a,b) Bind(C) Import Integer(C_int),Intent(In) :: a Integer(C_int),Intent(In),Optional :: b Integer(C_int) f End Function End Interface Integer(C_int) x,y x = f(3,14) y = f(23) Print *,x,y End Program int f(int *arg1,int *arg2) { int res = *arg1; if (arg2) res += *arg2; return res; }
f
への2番目の参照では、省略可能な引数b
がないため、nullポインターが渡されます。 上記は以下を出力します。17 23