インテル® Fortran コンパイラー 14.0 ユーザー・リファレンス・ガイド
C の文字列は NULL 終端であるのに対して Fortran の文字列は固定長であるため、C と Fortran が混在したプログラミングでは文字列の不一致が発生します。文字列を返す C ルーチンは、NULL 終端文字列へのポインターを返します。この場合、Fortran ルーチンは文字列の長さが分かりません。
Fortran ルーチンが C プログラムに文字列を返す場合、Fortran プログラムの文字列は NULL 終端文字でなければなりません。
次に、C ルーチンへのインターフェイスを宣言して C ルーチンを呼び出す Fortran コードを示します。この例では、C ルーチンによって返されるポインターを別の C ルーチンに渡すことができます。しかし、Fortran では文字列の長さが分からないため、そのままでは Fortran で使用できません。
Fortran のコード
! type(c_ptr) は Fortran プログラムでは制限されるため ! このプログラムは char* を返す C プログラムを宣言して ! 呼び出し、戻り値を異なる C プログラムに渡さなければ ! なりません program FCallsCReturnsCptr use, intrinsic :: iso_c_binding ! C ルーチンへのインターフェイスを宣言 interface type(C_PTR)function my_croutine1 ( input) bind(c) import integer(c_int), value :: input end function my_croutine1 subroutine my_cprint( string ) bind(c) import c_ptr type(C_PTR), value :: string end subroutine my_cprint end interface call my_cprint(my_croutine1(42)) end program
呼び出す C ルーチン
次に、Fortran ルーチンの呼び出しに使用する C コードを示します。Fortran ルーチンは C プログラムで出力される文字列を返します。この例で示されているように、Fortran から C に文字列を渡すのは比較的単純です。また、文字列は NULL 終端であるため、C プログラムで簡単に使用できます。
#include <stdio.h> char *my_croutine1 (int input) { static char temp[30]; temp[0] = '\0'; sprintf(temp, "in routine, you said %d", input); return temp; } void my_cprint (char *string) { printf ("cprint says %s\n", string); return; }
上記の例では、次の制限および動作が適用されます。
関数の長さと結果は、呼び出し文では指定しません。コンパイラーによって追加されます。
呼び出されたルーチンは、result によって指定された位置に結果文字列をコピーしなければなりません。length よりも長い文字のコピーはできません。
length よりも短い文字が返された場合、戻り位置の右側に空白がパディングされます。Fortran では、文字を終了するのにゼロは使用しません。
呼び出されたプロシージャーは void 型です。
次の例は、Fortran ルーチンを呼び出す C コードを示します。Fortran ルーチンは C プログラムで出力できる文字列を返します。
C のコード
#include <stdio.h> char *GetFortranWords(void); int main() { printf ("Fortran says this: %s\n", GetFortranWords()); return 0; }
呼び出す Fortran ルーチン
! このルーチンは C から呼び出され、呼び出し元で出力できる ! 文字列を返す function GetFortranWords bind(c, name="GetFortranWords") use, intrinsic :: iso_c_binding type(C_ptr) :: GetFortranWords character*30 returnval returnval = "I like to type words!" // char(0) GetFortranWords = C_LOC(returnval) return end