nAG Fortran コンパイラ 7.2 マニュアル

 
ナビゲーション:前へ   上へ   次へ

9.5 C相互運用性 [主に5.1]

9.5.1 ISO_C_BINDING モジュール

組込みモジュールISO_C_BINDINGには次のものが含まれています。
  • それぞれのCの型(例えばfloat)に対し、対応するFortran型の種別パラメタ として使用可能な名前付き定数
  • Cオブジェクトポインタと関数ポインタとの相互運用性を支援するC_PTR型と C_FUNPTR
  • FortranとCポインタを操作するための手続き

9.5.1.1 種別パラメタ

種別パラメタ名は対応するFortran型を利用するためのものです。例えば整数型に 対してはINTEGER、浮動小数点型に対してはREALがあります。 次の表はその対応を示したものです。 確実に利用可能なのはc_intのみである点に注意してください。もし対応する 型がない場合には値が負になります。

Cの型 Fortranの型と種別
_Bool LOGICAL(c_bool)
char CHARACTER(c_char) — For characters as text.
double REAL(c_double)
double _Complex COMPLEX(c_double_complex) or COMPLEX(c_double)
float REAL(c_float)
float _Complex COMPLEX(c_float_complex) or COMPLEX(c_float)
int INTEGER(c_int)
int16_t INTEGER(c_int16_t)
int32_t INTEGER(c_int32_t)
int64_t INTEGER(c_int64_t)
int8_t INTEGER(c_int8_t)
int_fast16_t INTEGER(c_int_fast16_t)
int_fast32_t INTEGER(c_int_fast32_t)
int_fast64_t INTEGER(c_int_fast64_t)
int_fast8_t INTEGER(c_int_fast8_t)
int_least16_t INTEGER(c_int_least16_t)
int_least32_t INTEGER(c_int_least32_t)
int_least64_t INTEGER(c_int_least64_t)
int_least8_t INTEGER(c_int_least8_t)
intmax_t INTEGER(c_intmax_t)
intptr_t INTEGER(c_intptr_t)
long INTEGER(c_long)
long double REAL(c_long_double)
long double _Complex COMPLEX(c_long_double_complex) or COMPLEX(c_long_double)
long long INTEGER(c_long_long)
short INTEGER(c_short)
signed char INTEGER(c_signed_char) — For characters as integers.
size_t INTEGER(c_size_t)

9.5.1.2 C_PTRC_FUNPTRの利用

これらは構造型名なのでType(c_ptr)Type(c_funptr)として使用できます。 Type(c_ptr)はCのvoid *とほぼ同等です。すなわちそれは任意のオブジェク トポインタを収容することができます。 Type(c_funptr)は関数ポインタについて同様の機能を提供します。

Cの‘int *’のような引数の場合に、Type(c_ptr)を使う必要はあり ません。通常の仮引数(この場合Integer(c_int)型のもの)をVALUE属性 無しで使用できます。 しかしながらより複雑なポインタ引数(例えばポインタからポインタ)、あるいはポイン タである変数や成分に対しては、Type(c_ptr)を使用する必要があります。

Type(c_ptr)Type(c_funptr)のNullポインタ定数は共に提供されていま す。これらはそれぞれC_NULL_PTRC_NULL_FUNPTRです。

Type(c_ptr)の値を作成する場合、関数C_LOC(X)をFortranオブジェクト Xに対して使用します(XTARGET属性を持つ必要があります)。 またこの際のFortranオブジェクトは多相、ゼロの大きさの配列、大きさ引継ぎ配列、 配列ポインタであってはなりません。 Type(c_funptr)の値を作成する場合には、関数C_FUNLOCを手続きに対して 使用します。この手続きはBIND(C)属性を持っている必要があります。

Type(c_ptr)もしくはType(c_funptr)がヌルであるかどうかを調べるには C_ASSOCIATED(C_PTR_1)関数を用いることができます。 この関数はC_PTR_1がヌルでない場合に限り.TRUE.を返します。 2つのType(c_ptr)もしくは2つのType(c_funptr)の値は C_ASSOCIATED(C_PTR_1,C_PTR_2)関数を用いて比較できます。 これはC_PTR_1C_PTR_2と同じCアドレスを持つ場合に限り.TRUE. を返します。

サブルーチンC_F_POINTER(CPTR,FPTR)TYPE(C_PTR)の値CPTRを スカラのFortranポインタFPTRに変換します。 このFortranポインタは任意の型で構いませんが(相互運用性のない型を含む)、多相で あってはなりません。 サブルーチンC_F_POINTER(CPTR,FPTR,SHAPE)TYPE(C_PTR)の値を Fortran配列ポインタFPTRに変換します。ここにSHAPEは1次元の整数配列 で、FPTRの次元数と同じ要素数を持つものです。結果となるFPTRの下限値 はすべて1です。

サブルーチンC_F_PROCPOINTER(CPTR,FPTR)が提供されています。これは TYPE(C_FUNPTR) CPTRをFortran手続きポインタFPTRに変換します。

これらすべての変換操作において、型や他の情報を正しく使うのはプログラマの責任で ある点に注意してください。

9.5.2 BIND(C)型

Cのstruct型に対応する構造型はその型をBIND(C)属性に与えることで 作成可能です。
例:
  TYPE,BIND(C) :: mytype
BIND(C)型の成分はCの型に対応する型を持っていなければならず、ポインタ もしくは割付けであってはなりません。 また、BIND(C)型はSEQUENCE型であってはなりません(それは既に SEQUENCE型であるかのような振舞いをします)。更に、型結合手続き や最終手続きを持っていてはならず、また拡張であってもなりません。

9.5.3 BIND(C)変数

Cのグローバル変数へのアクセスはFortran変数にBIND(C)属性を与える ことによって可能になります。 このような変数は一つのモジュール内でのみ宣言可能で、COMMON ブロック内では使用できません。 デフォルトではCの変数名はFortranの名前に変換されすべて小文字となります。 これと異なる名前を指定するにはNAME=節を利用します。
例:
  INTEGER,BIND(C,NAME="StrangelyCapiTalisedCName") :: x
Fortranコードの中において、変数はFortran名で参照され、C名で参照される わけではありません。

9.5.4 BIND(C)手続き

Cから呼び出すことができるFortranの手続きは、手続きの頭部分でBIND(C)属性を 指定して定義することができます。 デフォルトではFortran名を小文字に変換したC名が使用されます。異なる名前を 指定するにはNAME=節を利用します。
例:
  SUBROUTINE sub() BIND(C,NAME='Sub')
  ...
繰り返しますがCの名前はCでのみ使用し、Fortranの名前はFortranでのみ使用します。 Cの名前がすべて空白もしくはゼロの長さを持つ文字列であった場合、Cの名前は存在 しません。このような手続きであっても手続きポインタを介して(つまり TYPE(C_FUNPTR)変数にその値を代入することによって)Cからコールすること が可能です。

BIND(C)手続きはモジュール手続きもしくは明示的な引用仕様を持つ外部手続きでなければなりません。 内部手続き及び文関数であってはなりません。

BIND(C)手続きはサブルーチン、もしくはCの型に対応する型を持ったスカラ 関数でも構いません。 それぞれの仮引数はC型に対応する型の変数でなくてはならず、割付け、形状引継ぎ、 省略可能、ポインタであってはなりません。 仮引数がVALUE属性を持たない場合には、ポインタであるC仮引数に対応する ことになります。

Fortran手続きとそれをCから参照する例を示します:

SUBROUTINE find_minmax(x,n,max,min) BIND(C,NAME='FindMinMax')
  USE iso_c_binding
  REAL(c_double) x(*),max,min
  INTEGER(c_int),VALUE :: n
  INTRINSIC maxval,minval
  max = MAXVAL(x(:n))
  min = MINVAL(x(:n))
END

extern void FindMinMax(double *x,int n,double *maxval,double *minval);
double x[100],xmax,xmin;
int n;
...
FindMinMax(x,n,&xmax,&xmin);

これは、引用仕様ブロック内で呼ぶ出されるC手続きを記述することによって、Cの 手続きをFortranから呼び出すことも可能にします。
例を示します:

/* This is the prototype for a C library function from 4.3BSD. */
int getloadavg(double loadavg[],int nelem);

PROGRAM show_loadavg
  USE iso_c_binding
  INTERFACE
    FUNCTION getloadavg(loadavg,nelem) BIND(C)
      IMPORT c_double,c_int
      REAL(c_double) loadavg(*)
      INTEGER(c_int),VALUE :: nelem
      INTEGER(c_int) getloadavg
    END FUNCTION
  END INTERFACE
  REAL(c_double) averages(3)
  IF (getloadavg(averages,3)/=3) THEN
    PRINT *,'Unexpected error'
  ELSE
    PRINT *,'Load averages:',averages
  END IF
END

9.5.5 列挙

列挙は一群の同種の整定数を定義するもので、Cのenum宣言に相当します。
例:
  ENUM,BIND(C)
    ENUMERATOR :: open_door=4, close_door=17
    ENUMERATOR :: lock_door
  END ENUM
は次と等価です。
  enum {
    open_door=4, close_door=17, lock_door
  };
列挙子の一つに対して値が指定されなかった場合には、それは直前の値より1つ大きい 値(それが並びの中の最初の列挙子であった場合にはゼロ)を取ります。 特定の列挙子の集合に対して使われる種別は、KIND組込み関数を列挙子のいずれ かに対して用いることで見出すことができます。

BIND(C)節が必須である点に注意して下さい。標準はCとの相互運用を目的とした 列挙を規定しているに過ぎません。

© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks