読者です 読者をやめる 読者になる 読者になる

趣味で計算流砂水理

Computational Sediment Hydraulics for Fun

python+fortran:2003+OOP

本業が忙しくて全然だめです。

python+fortran:2003+OOP

以前書いた話の続きですが、pythonからfortranのdllを使うときもやっぱりOOPで書きたいので、チャレンジしてみました。

結果から言うと、main文に共有moduleを設け、その中で共有のclassを設定することにより雰囲気はでました。 C系だとpythonからobjectを渡せるのでこんなことをする必要はないと思いますが、fortranだとこれが限界です。

あと忘れないように書いておくと、fortranのfunctionは使えません。

!file name : test.f90
!class
module classModel
    implicit none
    private    
    type, public :: model
        DOUBLE PRECISION :: x
    contains
        procedure, public :: init
    end type
contains

subroutine init(self, x)
    class(model) :: self
    DOUBLE PRECISION, INTENT(IN) :: x
    self%x = x
end subroutine

end module classModel

!main
module pubMod
    use classModel
    CLASS(model), ALLOCATABLE :: m
end module

subroutine init(x)
    !DEC$ ATTRIBUTES DLLEXPORT :: init
    use pubMod
    DOUBLE PRECISION, INTENT(IN) :: x
    allocate(m)
    call m%init(x)
end subroutine

subroutine plus(y, ans)
    !DEC$ ATTRIBUTES DLLEXPORT :: plus
    use pubMod
    DOUBLE PRECISION, INTENT(IN) :: y
    DOUBLE PRECISION, INTENT(OUT) :: ans
    ans = m%x + y
end subroutine
@echo off
gfortran -std=f2003 -shared -o test.dll test.f90
import numpy as np
from ctypes import *

f = np.ctypeslib.load_library("test.dll",".")

f.init_.argtypes = [POINTER(c_double)]
f.plus_.argtypes = [POINTER(c_double),POINTER(c_double)]

x,y = 2.0 ,1.1
x = c_double(x)
y = c_double(y)
res = c_double()

f.init_(byref(x))
f.plus_(byref(y), byref(res))
print(res.value) # 3.1

del f

DBに置いておくので回してみて下さい。

これを使ってsection2Dモデルの拡張版を書いているので近々公開します。

WindowsFORTRAN環境構築について訂正

先日gfortranの4.8が良いって言いましたが、6.0代も安定してますのでこっちのほうが良さそうです。

64bit の Windows10 上でフリーの fortran コンパイラを導入して、簡単なプログラムを作成する - あらきけいすけの雑記帳

exe一発です。

windowsfortranコンパイル用のmakefileって....

最近知ったのですが、inteのnmakeとgmakeって結構違いますね。どちらでもmake一発でという思いでmakeファイルを書いていたので、残念です。

書く気をなくしました。