FortranのCOMMONブロックをC++から扱う

少しメモ書きとして垂れ流し状態にするので、ご容赦を。

Fortranの引数は、C言語のポインタに変換することを覚えておけば、引数で渡すときは特に問題なし。
ただし、いちいち大量の設定データなどを、CからFortranに渡すのは大変なので、初期値っぽく Fortran の common ブロックを使うのがよい。

! common block
module commodule
    implicit none
    integer posx, posy
    common /compos/ posx, posy
contains
    subroutine comsub1()
        print *, "comsub1: ", posx, posy
    end subroutine comsub1
end module commodule

のように、commodule というモジュールの中に、compos という名前の common ブロックを作っておく。compos は、commodule モジュール内で共有できるし、モジュールの外に出してしまえば所謂グローバル変数として扱うことができる。ただし、大きなプログラムになると変数名がバッティングするので、モジュール内に入れるかなんらの命名規則を作ったほうがよかろう。

extern "C" {
	// common でデータを共有する
	struct ccompos {
		int posx;
		int posy;
	};
	// Fortran側のデータを構造体で参照する
	// プレフィックスはつかない模様
	extern ccompos COMPOS;
	// intel fortran では、モジュール名+_mp_+関数名でマッピングする
	// モジュール名、関数名は大文字
	void COMMODULE_mp_COMSUB1( void );
}

C++から扱うときは、common ブロックのパラメータをそのまま構造体にする。この順番は fortran で定義した順番通りにする。名前のない common ブロックの場合はどうするのか不明。
データ領域は、fortran で作成したライブラリ内にあるので、C++からは extern で参照しておく。このときの名前が、fortran で定義した common ブロックの名称になる。
common ブロックへの読み書きは、fortran からも c++ からも同様に行える。

実は、先頭のアドレスだけわかれば後はポインタでアクセスが可能なので、構造体を定義しなくても名前からアクセスできるマクロを作れそうだが、あまりスマートにいきそうにないのでやめておく。

カテゴリー: 開発, C++, Fortran パーマリンク