関連情報
ホーム > 製品 & サービス > NAG Fortran コンパイラ > Fortran Builder > DLL を Python から利用する例

Fortran Builder
DLL を Python から利用する例

Fortran Builder は、実行形式(.exe)以外にもダイナミックリンクライブラリ(.dll)やスタティックライブラリ(.a)の作成が行えます。特に DLL は様々な環境から使える強力な仕組みであるため、Fortran で書いた計算ルーチンを Excel や Python などの他の環境から使うことが可能です。

ここでは、Fortran Builder を用いて DLL ファイルを作成し、Python から呼び出す例を示します。

この例では、

これにより、C のインターフェースを介して、Python から Fortran 手続を呼び出しています。

  • @ DLL プロジェクトを作成する
  • A プロジェクトにソースファイルを追加する
  • B ソースファイルにプログラムを書く
  • C プロジェクトをビルドする(DLL ファイルを生成する)
  • ※ プロジェクトフォルダーを開く
  • D DLL を Python から呼び出す
  • (追記)
    C からの呼び出し例
    ラッパー例1
    ラッパー例2
    その他のプログラム例

    @ DLL プロジェクトを作成する

    メニューから「ファイル > 新規作成 > プロジェクト」を選択してください。

    プロジェクトの作成メニュー

    以下のような画面が表示されますので、「ダイナミックリンクライブラリ」を選択後に「プロジェクトの名前」を myflib として「次へ」ボタンを押してください。

    以下のような画面が表示されますが、このまま「OK」ボタンを押して次に進んでください。

    以下のような画面が表示されれば、DLL プロジェクトの作成は無事行われています。
    次のステップに進んでください。

    A プロジェクトにソースファイルを追加する

    メニューから「ファイル > 新規作成 > ファイル」を選択してください。

    ファイルの作成メニュー

    以下のような画面が表示されますので、「Fortran 自由形式ソースファイル」を選択後に「OK」ボタンを押してください。

    ファイルの作成ダイアログ1

    以下のような画面が表示されますので、「ファイル名」を myprog として「OK」ボタンを押してください。

    以下のような画面が表示されれば、ソースファイルの作成は無事行われています。
    次のステップに進んでください。

    B ソースファイルにプログラムを書く

    以下のソースプログラムを入力してください。
    倍精度実数 a と b を引数にとり、a + b を倍精度実数として返す関数です。

    特に、Fortran 2003 から導入された C との相互利用可能性 を用いて書かれていることに注意してください。
    (これにより、インターフェース的には、外部から C 関数として呼び出すことができます。)

    function myfunc(a, b) bind(c, name = "myfunc")
      use iso_c_binding
      real(c_double), value, intent(in) :: a, b
      real(c_double) myfunc
      myfunc = a + b
    end function
    

    入力が終わったら、メニューから「ファイル > 上書き保存」(または Ctrl + S)を選択してください。

    上書き保存メニュー

    C プロジェクトをビルドする(DLL ファイルを生成する)

    メニューから「プロジェクト > ビルド」を選択してください。

    ビルドメニュー

    問題が無ければ、メッセージウィンドウに以下のように表示され、プロジェクトフォルダーに DLL ファイルが作成されます。

    ※ プロジェクトフォルダーを開く

    メニュー「表示 > プロジェクトフォルダー」から、プロジェクトフォルダーを直接開くことができます。

    プロジェクトフォルダーの表示メニュー

    フォルダーの中に、DLL ファイル(myflib.dll)が作成されていることが分かります。

    D DLL を Python から呼び出す

    以下に Python のコード例を示しますが、DLL ファイルのパスはユーザー環境に合わせて適宜書き換えてください。

    特に、Python の ctypes モジュール(C と互換性のあるデータ型を提供し、DLL/共有ライブラリ内の C 関数を呼び出すためのモジュール)を利用していることに注意してください。

    from ctypes import *
    
    myflib = WinDLL("myflib.dll")
    
    myflib.myfunc.restype = c_double
    myflib.myfunc.argtypes = [c_double, c_double]
    
    a = 2.0
    b = 3.0
    print(myflib.myfunc(a, b))
    

    実行結果:

    5.0
    

    (追記)C からの呼び出し例

    C から呼び出す場合は以下の様になります。

    #include <stdio.h>
    
    extern double myfunc(double a, double b);
    
    int main(int argc, char *argv[])
    {
      double a, b;
    
      a = 2.0;
      b = 3.0;
      printf("%f\n", myfunc(a, b));
    
      return 0;
    }
    

    (追記)ラッパー例1

    既存の外部手続(サブルーチン・関数)に手を加えたくない場合は、例えば以下の様に、ラッパーを書くという方法もあります。

    function myfunc(a, b)
      double precision, intent(in) :: a, b
      double precision myfunc
      myfunc = a + b
    end function
    
    function myfunc_wrap(a, b) bind(c, name = "c_myfunc")
      use iso_c_binding
      interface
        function myfunc(x, y)
          double precision, intent(in) ::  x, y
          double precision myfunc
        end function
      end interface
      real(c_double), value, intent(in) :: a, b
      real(c_double) myfunc_wrap
      myfunc_wrap = myfunc(a, b)
    end function
    

    この場合、Python からの呼び出しは以下の様になります。

    from ctypes import *
    
    myflib = WinDLL("myflib.dll")
    
    myflib.c_myfunc.restype = c_double
    myflib.c_myfunc.argtypes = [c_double, c_double]
    
    a = 2.0
    b = 3.0
    print(myflib.c_myfunc(a, b))
    

    (追記)ラッパー例2

    既存のモジュール手続(サブルーチン・関数)に手を加えたくない場合は、例えば以下の様に、ラッパーを書くという方法もあります。

    module mymod
      implicit none
    contains
      function myfunc(a, b)
        double precision, intent(in) :: a, b
        double precision myfunc
        myfunc = a + b
      end function
    end module
    
    function mymod_myfunc_wrap(a, b) bind(c, name = "c_mymod_myfunc")
      use mymod
      use iso_c_binding
      real(c_double), value, intent(in) :: a, b
      real(c_double) mymod_myfunc_wrap
      mymod_myfunc_wrap = myfunc(a, b)
    end function
    

    この場合、Python からの呼び出しは以下の様になります。

    from ctypes import *
    
    myflib = WinDLL("myflib.dll")
    
    myflib.c_mymod_myfunc.restype = c_double
    myflib.c_mymod_myfunc.argtypes = [c_double, c_double]
    
    a = 2.0
    b = 3.0
    print(myflib.c_mymod_myfunc(a, b))
    

    (追記)その他のプログラム例

    より複雑なプログラム例は「Python から Fortran を呼び出す例」をご参照ください。


    Results matter. Trust NAG.
    Privacy Policy | Trademarks