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

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

11.8 高度なC相互運用性

  • [7.0] 組込みモジュールISO_C_BINDINGC_FUNLOC関数は、相互運用不可能な手続き引数を受け入れます。 生成されたC_FUNPTR値は、C関数ポインターに変換しないでください。 ただし、ISO_C_BINDINGC_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_BINDINGC_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_LOCC_FUNLOC は 純粋手続とみなされ、C_F_POINTERC_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
    
Privacy Policy  /  Trademarks