【Fortran学習|豆知識】Fortranと他言語の架け橋!BIND(C)を使ったモジュール手続きの外部結合術

1. 導入:なぜBIND(C)が必要なのか

数値計算の現場では、計算の核となる部分をFortranで記述し、フロントエンドをPythonやC++で構築するケースが多々あります。しかし、Fortran特有の「名前修飾(マングリング)」という仕組みが壁となり、外部言語から関数を直接呼び出そうとするとリンクエラーが発生することがあります。ここで登場するのがBIND(C)です。これを使うことで、Fortranのモジュール手続きをC言語と互換性のある形式で公開し、言語の垣根を越えた高度な連携が可能になります。

2. 基礎知識:名前修飾と相互運用性

Fortranはコンパイラによってサブルーチン名を内部的に変換(例えば compute が compute_ になるなど)します。これを「名前修飾」と呼びます。C言語やPythonはこれを知らないため、関数が見つからずエラーになります。BIND(C)属性を付与すると、Fortranコンパイラに対して「C言語の規約に従った名前で書き出しなさい」と指示を出し、名前修飾を無効化します。これにより、多言語からFortranの資産を直接呼び出せるようになります。

3. 実装:モジュール内での指定方法

モジュール内で手続きを定義する際、subroutineの後に `bind(c, name=”公開する名前”)` を記述します。重要なのは、引数にも `value` 属性や `iso_c_binding` モジュールを利用して、C言語の型と完全に一致させることです。これにより、データ構造の不整合によるメモリ破壊などのバグを未然に防ぐことができます。

4. サンプルプログラム

以下のコードは、Fortranのモジュール手続きをCから呼び出し可能な形式で定義する例です。

module calculator
use iso_c_binding, only: c_double
implicit none

contains

! BIND(C)を使って名前修飾を回避
! name引数でC言語から見える名前を明示的に指定します
subroutine compute(input_val, result_val) bind(c, name=”compute_fortran”)
use iso_c_binding, only: c_double
implicit none

! C言語のdouble型とFortranのreal(c_double)を対応させる
real(c_double), intent(in) :: input_val
real(c_double), intent(out) :: result_val

! 簡単な計算処理
result_val = input_val 2.0_c_double

! 処理結果をコンソールに出力
print , “Fortran側での計算完了”
end subroutine compute
end module calculator

5. 応用・注意点:現場でのトラブル回避

実装時に最も陥りやすい罠は「データ型の不一致」です。Fortranの `real` はデフォルトで4バイトや8バイトと環境依存しやすいですが、`iso_c_binding` モジュール内の `c_double` や `c_int` を必ず使用してください。また、配列を渡す場合は、Fortranのメモリレイアウトが「列優先(Column-major)」であるのに対し、C言語が「行優先(Row-major)」である点に注意が必要です。多言語連携の際は、配列のインデックス順序を意識した設計が、堅牢なシステム構築の鍵となります。

コメント

タイトルとURLをコピーしました