🗂

Fortran と C++ を Visual Studio で連携する

に公開

KMC Advent Calender 2025 の 10 日目の記事です。昨日 (120 時間前) の記事は Rust製ゲームエンジンBevy 0.17で、ゼロから落ち物パズルを実装する でした。非常に興味深いと思います。今回の記事に登場する言語と比較すると、Rust は本当に魅力的ですね。

動機

「そもそも Fortran ってなに」という人もいるかもしれないので、生成AIの回答を載せておきます。

🤖 Fortran(Formula Translation)は、1950年代に科学技術計算を目的として開発された高級プログラミング言語です。
配列演算や数値計算に強く、線形代数や微分方程式などの分野で高い性能を発揮します。
長い歴史の中で改良が重ねられ、現在の Fortran はモジュール化や並列処理、オブジェクト指向的な記述も可能です。
そのため、最新のスーパーコンピュータを用いる HPC(高性能計算)分野でも今なお広く利用されています。
一方で、レガシーコード資産が非常に多く、過去のコードと向き合いながら運用・発展させていく言語でもあります。

さて、近年はGPU 計算需要に伴い、Fortran の将来性が危ぶまれています。

📉 アメリカ「米国 HPC 分野では、ここ10年で Fortran 使用率が半減した」

🏢 NVIDIA 社「CUDA の Fortran サポート、将来的に維持が難しくなるかもしれない[1]。打ち切るかも」

🧑‍🔬 研究者 A 「GPU 向けツールチェインは C++ 中心ですね。Fortran は微妙」

🧑‍🔬 研究者 B 「なんでレガシーな Fortran を使うのですか? 最近だと Julia[2] とかもありますよ」

🧑‍🔬 研究者 C 「これからは脱 Fortran の時代です。Fortran を大学で教えるのをもうやめましょう」

🧑‍🎓 学生 A 「正直、Fortran は好きじゃないです。GPU もやりたいし、就職のこと考えたら C++ かなって」

🧑‍🎓 学生 B「Fortran コードは汚いイメージがあります」

🧑‍🎓 学生 C「Fortran のコーディング体験が最悪です。どうしてまともな LS がないのですか」

嘆かわしいことですが、至るところでこのような Fortran を厭う声が聞こえてきます。

しかしながら、計算科学関連の研究室では、代々受け継がれてきた Fortran (or FORTRAN) コードと向き合う義務があります[3]。

実は、私自信も現在 Fortran に立ち向かう場面に直面しています。

そこで今回は、普段使用している計算資源環境ではなく、ローカルの Windows 環境で Fortran を動かしてみようと思います。

また、将来的に C++ / CUDA を取り入れることも想定し、Fortran と C++ を併用してプログラムを動作させてみます。

Fortran と戯れることにより、少しでも Fortran に対する抵抗を無くすのが今回の目的です。

Visual Studio に Fortran を導入する

Windows の Fortran 環境について調査すると、Visual Studio に Intel Fortran Compiler を導入するのが堅実なようでした[4]。それでやってみます。

必要なものをインストール

  • Visual Studio 2022

  • Intel oneAPI Base Toolkit

  • Intel oneAPI HPC Toolkit

https://www.intel.com/content/www/us/en/developer/tools/oneapi/overview.html

Intel oneAPI のインストールをやってみると、Visual Studio を検出して自動的に Visual Studio へ統合してくれる感じでした。

プロジェクト作成

インストールが終わると、Visual Studio に Fortran テンプレートが追加されます。

「Empty Project」を選んで新規ソリューションを作成します。

image-20251215161508393

C++, Fortran プロジェクトの追加

Visual Studio + Intel Fortran では、一つのプロジェクト内に Fortran と C++ を混在させてコンパイルさせることが出来ないようでした。

そのため、ソリューション内に C++ プロジェクトと Fortran プロジェクトを隔てて作成します。今回は、C++ 側をエントリーポイント、Fortran 側を DLL にしてビルドをします (Fortran 側を静的ライブラリとしてビルドすることも試したのですが、リンクエラーが解決出来ず断念しました)。C-Fortran の FFI で C++ 側から Fortran 実装の関数を呼び出します。

ソリューションエクスプローラーのソリューションを右クリックして「追加」➡️「新しいプロジェクト」を選択し、まず「C++ コンソールアプリ」を選んでプロジェクトを作成します。

同様の操作で、Fortran 用の「Dynamic-link Library」を選んでプロジェクトを作成します。

今回は、プロジェクト名をそれぞれ CApp, FortranLib としました。

fortran-toy (ソリューション)
├─ CApp (C++ プロジェクト)
└─ FortranLib (Fortran ライブラリ)

image-20251215162630730

プロジェクト設定

  1. C++ 側のプロジェクト (CApp) のプロパティを編集します。

​ ソリューションエクスプローラーから CAppを右クリック ➡️「プロパティ」から以下のように設定します。

  • 「構成プロパティ」➡️「リンカー」➡️ 「追加の依存ファイル」:

    $(SolutionDir)FortranLib\$(Platform)\$(Configuration)\FortranLib.lib

  • 「構成プロパティ」➡️「ビルドイベント」➡️「ビルド後のイベント」➡️「コマンドライン」:

    xcopy /Y /D /I ^
      "$(SolutionDir)FortranLib\$(Platform)\$(Configuration)\FortranLib.dll" ^
      "$(TargetDir)"
    
  1. ソリューションエクスプローラーから CAppを右クリック ➡️「ビルドの依存関係」➡️「プロジェクトの依存関係」から FortranLib にチェックを入れます。

C++ ファイルと Fortran ファイル作成

それぞれのプロジェクトにファイルを追加します。

  fortran-toy (ソリューション)
  ├─ CApp (C++ プロジェクト)
+ │  └─ CApp.cpp
  │
  └─ FortranLib (Fortran ライブラリ)
+    └─ solver.f90

内容

// CApp.cpp

#include <iostream>

extern "C" {
    void fortran_add(double a, double b, double* result);
}

int main()
{
    double r = 0.0;
    fortran_add(1.0, 2.0, &r);
    std::cout << r << std::endl;
}

! solver.f90

module solver_mod
  use iso_c_binding
contains
  !DEC$ ATTRIBUTES DLLEXPORT :: add
  subroutine add(a, b, result) bind(C, name="fortran_add")
    real(c_double), value :: a, b
    real(c_double) :: result
    result = a + b
  end subroutine
end module

Fortran 側では、!DEC$ ATTRIBUTES DLLEXPORT :: add のように C++ 側に見せる関数に DLL 用のシンボル名を明示する必要があるようです。

実行結果

動きました。

3

おわりに

感動しました。

脚注
  1. HPC 界隈でよく耳にすると思うのですが、インターネット上では主張の裏付けをあまり見かけないようでした。 ↩︎

  2. The Julia Programming Language (https://julialang.org/) ↩︎

  3. 古代言語FORTRANの解読について (https://zenn.dev/ohno/articles/b104fe8f506439) ↩︎

  4. Intel oneAPIで作る無償のFortran開発環境 (https://qiita.com/Kazutake/items/a069f86d21ca43b6c153) ↩︎

GitHubで編集を提案

Discussion