FORTRANコードをCで使う

fortran

仕事で古い FORTRAN77 のコードを .NET Framework (C# アプリ)から呼ぶことになり、ビルドと呼ぶ手順について検証しました。それまで漠然としたイメージしかなかった FORTRAN を触れる良い機会だったので、覚え書き程度に一般的な情報の部分を記事に残しておきたいと思います。

導入

GNU Compiler Collection が動く UNIX 系の OS であれば、ディストリごとの公式リポジトリに GFortran が準備されていると思います。

$ sudo apt-get install gfortran

APT システムの環境だと、上のコマンドを実行するだけで一式入ります。今回のターゲットは FORTRAN77 で、GFortran は 9x 対応のようですが、9x は 77 の互換性を維持しているらしいので、特にバージョンを意識する必要はなさそうです。60年近い FORTRAN の歴史の中では比較的に新しい規格である 2003、2008 についての対応状況は、他のコンパイラを合わせてもあまり芳しくなさそうな印象を受けました。

なお、Microsoft Windows でも Microsoft Visual Studio と Intel Parallel Studio for Fortran (有償)を導入すれば開発が可能なようですが、UNIX 開発ツール群の Windows 移植版 MSYS/MinGW に GFortran が入っており、そちらで Win32 な DLL や EXE も生成できてしまいますので、FORTRAN ベースでリソースをガリガリいじったり Windows 特有の機能をバリバリ呼び出したりしない限り、さくっと UNIX 互換ツール環境を入れてしまった方が賢明そうです。

ビルド

次にテストの FORTRAN、C それぞれのコードを示します。

FORTRAN 側のサブルーチン twice は与えられた整数値を 2 倍して、実数値で返す簡単なものです。呼び出しもとの C 側では、この関数を引数 10 を与えて呼び出し、結果を印字しているだけです。

今回は FORTRAN で書いたコードをオブジェクトファイルにして、C で書いたコードと静的リンクして C からサブルーチンを呼び出すので、次のようにビルドします。

$ gfortran -c my-test-lib.f

-c オプションでオブジェクトファイルを生成します。GFortran は GCC のコンパイラの一種なので、C/C++ での開発時のオプションがそのまま流用できて便利です。これを実行すると、オブジェクトファイル my-test-lib.o が生成されます。 次に、

$ gcc -lgfortran my-test-lib.o sample.c

を実行すると、sample.c をコンパイルしたのち、my-test-lib.o とリンクを行い、実行可能形式の a.out が生成されます。見てのとおりですが、libgfortran にもリンクしなければなりません。

実行

$ ./a.out
result: 20.000000

ちゃんと動いているようです。C# アプリから呼び出す場合は、MinGW で EXE としてビルドして外部プロセスとして呼び出すか、Win32 DLL としてビルドして [DllImport()] してやればいいと思います。(クラスを呼び出すわけじゃないから、C++/CLI でラップする必要もなさそう)

コード解説

FORTRAN を書くのは初めてなので、解説…という立派なものではありませんが、ちょっと触ってみてポイントになるところをメモしておきます。

  • オブジェクトファイルは C で関数単位でコンパイルしておくのと同様、サブルーチン単位(もしくは複数のサブルーチン単位)でコンパイルして利用することが可能。
  • サブルーチン宣言行の末尾に bind(C) を付与しておくと、サブルーチン名で C 側からアクセスできるようになる。
  • bind(C) を付与すると、FORTRAN 内からのサブルーチンコールができなくなる?
  • implicit 文で仮引数 n, r の型を宣言している。
  • C の関数のような戻り値の記法はない。そのため、C 側から見たサブルーチンはすべて戻り値が void となる。
  • サブルーチンから値を返したい場合は、C 側からポインタを渡してその中に書き込ませる。
  • 戻り値以外であっても、値はポインタとして渡す必要がある。

2015/8/30 追記

Microsoft Windows でも MinGW にて、mingw32-basemingw32-gcc-fortran パッケージをインストールすると上と同じコードをビルド・実行することができました。

gfortran-on-mingw

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください