【入門編】C_PTRおよびC_FUNPTRによるポインタの相互運用 – モダンFortran言語仕様と実践実践マスター

C言語とFortranを「メモリの橋」で繋ぐ:C_PTRとC_F_POINTERの実践的ガイド

こんにちは。かつて宇宙の深淵を計算で追いかけていた、Fortranの設計者です。
君たちが今、C言語やPythonといったモダンな言語の知識を武器に、Fortranという「計算の要塞」に足を踏み入れようとしていること、心から歓迎します。

Fortranは一見古臭く見えるかもしれませんが、スパコンの心臓部では今なお最強の言語です。しかし、現代の計算環境ではC/C++で作られたライブラリやGPUのメモリを扱う機会が避けられません。そんなとき、最も重要になるのが`ISO_C_BINDING`という「翻訳機」です。

今日は、C言語のポインタをFortranに持ち込み、安全に調理するための「メモリの橋」の架け方を伝授しましょう。

1. そもそも、なぜ「ポインタ」が厄介なのか?

C言語のポインタは、メモリ上の「住所」です。一方、Fortranの標準的な変数は「実体」を直に扱います。この「住所」をFortranに持ち込むと、コンパイラは「これは何が入っているのか?」と混乱してしまいます。

そこで登場するのが、`type(c_ptr)` です。これは「C言語の住所を保持するための専用の箱」だと考えてください。これ自体はメモリの中身を覗くことはできませんが、住所を安全に保管しておくための「名刺」のような役割を果たします。

2. 実践:CのメモリをFortranで覗く手順

C言語で確保したメモリをFortranで配列として扱うには、以下の3ステップが必要です。

1. `c_ptr` でアドレスを受け取る。
2. `c_f_pointer` を使って、Fortranの配列(ポインタ変数)に紐付ける。
3. Fortran側で自由にいじる。

サンプルコード:Cのメモリを配列としてマッピングする

use, intrinsic :: iso_c_binding
implicit none

! 1. 住所を保管するための箱を用意
type(c_ptr) :: c_addr
! 2. Fortran側で扱う配列の定義(ポインタ属性を付けるのがコツ)
real(c_float), pointer :: f_array(:)
integer :: n = 10

! — ここでC言語側から受け取ったアドレスが c_addr に入っていると仮定 —
! c_addr = get_c_memory_address()

! 3. 橋渡し:Cの住所(c_addr)を、Fortranの配列(f_array)に変換する
! shape=(/n/) で配列のサイズを教えるのがポイントです
call c_f_pointer(c_addr, f_array, shape=[n])

! これで f_array(1)~f_array(n) にアクセス可能!
f_array(1) = 3.14
print , “Fortranから見た値:”, f_array(1)

3. 数値計算屋が絶対に守るべき「3つの鉄則」

現場で長年デバッグをしてきた経験から、これだけは守ってほしいというルールがあります。

① `target` と `pointer` の関係を意識する

Fortranで`c_f_pointer`を使う際、ターゲットとなるポインタ変数には必ず `pointer` 属性を付けてください。また、Fortranの変数をC側に渡すときは、その変数に `target` 属性が必要です。そうしないと、コンパイラが「こいつは途中で移動するかもしれない」と判断し、無駄なコピー処理(オーバーヘッド)を生成して速度がガタ落ちします。

② 配列の並び順(メモリアクセス)に注意

C言語は「行優先(Row-major)」、Fortranは「列優先(Column-major)」です。
C言語の `float data[10][10]` をFortranに渡すと、インデックスの解釈が逆転します。特に多次元配列を扱う際は、C側とFortran側で添字を入れ替えるか、メモリ配置を設計段階で揃える必要があります。ここを疎かにすると、計算結果が壊滅的な数値になります。

③ 解放(Free)の責任を明確にする

`c_f_pointer` はあくまで「見ているだけ」です。C側で `malloc` したメモリを、Fortran側で勝手に解放することはできません。C側で `free` する関数を定義し、それを `bind(c)` でFortranから呼べるようにするのが、メモリリークを防ぐ唯一の解です。

最後に:君たちへの励まし

「Fortranは難しい」と言う人がいますが、それは「Fortranの型システムやメモリ管理の厳格さ」を無視しようとするからです。逆に言えば、この厳格さは「計算の再現性と速度を保証するための規律」です。

まずは、小さなC言語の配列をFortranで読み書きするところから始めてみてください。コンパイラが吐き出す警告を一つ一つクリアしていく過程で、計算機そのものの挙動が手に取るようにわかるようになるはずです。

何か詰まったら、いつでも戻ってきてください。君たちの数値計算が、明日の科学を少しでも前へ進めることを期待しています。頑張ってくださいね!

コメント

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