4

Fortran ライブラリ コードの一部を C に変換して、最終的に Fortran ラッパーを使用した C 関数を作成しています。Fortran 95 を使用しています。

割り付け可能な配列を処理するための推奨される方法は何ですか?

  1. 割付け配列を C 関数に渡して、C 関数内で malloc することはできますか? (C 関数は、malloc されるサイズを認識しています)

  2. Fortran プログラムで、C 関数で割り当てられたものを解放できますか? そのため、最後にクライアントの Fortran アプリケーションが配列の割り当てを解除するか、メモリを解放する C 関数を呼び出す必要があります。

小さな例またはそのリンクをいただければ幸いです。

4

1 に答える 1

6

Fortran 95 では、Fortran プロシージャを含め、割付け可能な配列を割付け可能なものとして「渡す」ことはできません。

Fortran 2003 では、C 関数は配列のストレージを malloc し、それを ISO_C_BINDING 組み込みモジュールからの C_PTR として Fortran 側に返すことができます。C_PTR が指すストレージには、Fortran POINTER および ISO_C_BINDING モジュールの C_F_POINTER プロシージャーを使用してアクセスできます。

配列のストレージを解放するために、Fortran 側は再び C プロシージャを呼び出し、C_PTR を渡します。C_PTR は、C 関数が free の呼び出しで使用します。

#include "stdlib.h"
int *create_storage()
{
   /* Array of four integers. */
   return malloc(sizeof(int) * 4);
}

void destroy_storage(int *ptr)
{
   free(ptr);
}


PROGRAM fortran_side
  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_INT
  IMPLICIT NONE
  INTERFACE
    FUNCTION create_storage() BIND(C, NAME='create_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE
      TYPE(C_PTR) :: create_storage
    END FUNCTION create_storage
    SUBROUTINE destroy_storage(p) BIND(C, NAME='destroy_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE
      TYPE(C_PTR), INTENT(IN), VALUE :: p
    END SUBROUTINE destroy_storage
  END INTERFACE
  TYPE(C_PTR) :: p
  INTEGER(C_INT), POINTER :: array(:)
  !****
  p = create_storage()
  CALL C_F_POINTER(p, array, [4])   ! 4 is the array size.
  ! Work with array...
  CALL destroy_storage(p)
END PROGRAM fortran_side

Fortran 201X では、C ヘッダー ファイルと関数を提供して、C が Fortran 割り当て可能変数を直接操作できるようにすることができます。

于 2013-10-02T22:38:33.330 に答える