C/C++へのコールバック関数ポインタとしてfortran 77関数を渡すことは可能ですか? もしそうなら、どのように?
Web で見つけた情報は Fortran 90 以降に関するものですが、私のレガシー コード ベースは 77 です。
どうもありがとう
C/C++へのコールバック関数ポインタとしてfortran 77関数を渡すことは可能ですか? もしそうなら、どのように?
Web で見つけた情報は Fortran 90 以降に関するものですが、私のレガシー コード ベースは 77 です。
どうもありがとう
FORTRAN 77 で実行できる場合は、コンパイラとプラットフォーム固有になります。Fortran 2003 の新しい ISO C バインディングは、Fortran と C、および C++ などの C の呼び出し規則に従う、または従うことができる任意の言語を混在させる標準的な方法を提供します。正式には Fortran 2003 の一部であり、Fortran 2003 全体を完全にサポートする Fortran コンパイラはほとんどありませんが、ISO C バインディングは、gfortran、g95、Sun、ifort などを含む多数の Fortran 95 コンパイラでサポートされています。特定のメソッドについて何らかのメソッドを考え出すよりも、これらの Fortran 95 コンパイラの 1 つと ISO C Binding メソッドを使用することをお勧めします。FORTRAN 77 は Fortran 95 のサブセットであるため、Fortran 95 を使用してこの新しい機能を追加し、レガシー コードをこれらのコンパイラのいずれかでコンパイルしてみませんか?
ISO C Binding を使用して C から Fortran プロシージャを呼び出しましたが、それらをポインターとして渡していません。それは可能であるべきです。手順は次のとおりです。
1) Bind(C) 属性を使用して Fortran 関数を宣言します。
2) C の型と一致する integer(c_int) などの特殊な型を使用して、すべての引数を宣言します。
ステップ 1 と 2 により、Fortran 関数が C と相互運用可能になります。
3) Fortran 組み込み関数 "c_funloc" を使用して、この Fortran 関数への C ポインターを取得し、ポインター値を "c_funptr" 型のポインターに割り当てます。
4) Fortran コードでは、インターフェイスを使用して関数ポインターを渡す C ルーチンを宣言し、Fortran 用語で宣言しますが、Fortran コンパイラーが認識できるように、Bind(C) 属性と相互運用可能な型を使用します。 C 呼び出し規則を使用して、C ルーチンを Fortran と相互運用可能にします。
その後、Fortran コードで C ルーチンを呼び出すときに、ステップ 3 で作成した関数ポインターを渡すことができます。
更新: コード例: Fortran メイン プログラム「test_func_pointer」は、Fortran 関数「my_poly」へのポインターを C ルーチン「C_Func_using_Func_ptr」に渡し、その C 関数から結果を受け取ります。
module func_pointer_mod
use, intrinsic :: iso_c_binding
implicit none
interface C_func_interface
function C_Func_using_Func_ptr ( x, Func_ptr ) bind (C, name="C_Func_using_Func_ptr")
import
real (c_float) :: C_Func_using_Func_ptr
real (c_float), VALUE, intent (in) :: x
type (c_funptr), VALUE, intent (in) :: Func_ptr
end function C_Func_using_Func_ptr
end interface C_func_interface
contains
function my_poly (x) bind (C, name="my_poly")
real (c_float) :: my_poly
real (c_float), VALUE, intent (in) :: x
my_poly = 2.0 * x**2 + 3.0 * x + 5.0
return
end function my_poly
end module func_pointer_mod
program test_func_pointer
use, intrinsic :: iso_c_binding
use func_pointer_mod
implicit none
type (c_funptr) :: C_func_ptr
C_func_ptr = c_funloc ( my_poly )
write (*, *) C_Func_using_Func_ptr ( 2.5_c_float, C_func_ptr )
stop
end program test_func_pointer
と
float C_Func_using_Func_ptr (
float x,
float (*Func_ptr) (float y)
) {
return ( (*Func_ptr) (x) );
}