ferrad
February 14, 2024, 12:01pm
1
I am calling Fortran from Python as follows:
import ctypes as ct
lib = ct.CDLL('x64\\Debug\\main2.dll')
f = getattr(lib,'MAIN2_MOD_mp_MAIN2')
f.restype = None
x = [2.0, 0.0]
def fun(x):
objf = c_double(0.0)
f((c_double * len(x))(*x), byref(objf))
return objf
The Fortran is:
module main2_mod
contains
!dec$ attributes dllexport :: main2
subroutine main2(x,f)
implicit none
real(8), intent(inout) :: x(*)
real(8), intent(out) :: f
This works fine when x is not changed in the Fortran. However when I change x, the new values do not get returned to Python.
egio
February 14, 2024, 12:22pm
2
I strongly suggest you to use numpy.ctypeslib.ndpointer
You can see an example in:
from ctypes import CDLL, c_int, c_size_t, c_double, POINTER
import os
import numpy as np
from numpy.ctypeslib import ndpointer
_path = os.path.dirname(__file__)
_library = CDLL(os.path.join(_path, "ecerad_py_interface.so"))
#subroutine radiation_temperature(nr, ns, r, ne, te, b, rs, theta, te_rad, te_rad_profile) bind(C)
# use iso_c_binding
# integer(c_int), value :: nr, ns
# real(c_double),intent(in) :: r(nr), ne(nr), te(nr), b(nr)
# real(c_double),intent(in) :: rs(ns), theta
# real(c_double), intent(out) :: te_rad(ns), te_rad_profile(nr,ns)
_library.radiation_temperature.restype = None
_library.radiation_temperature.argtypes = [
c_int, # NR
c_int, # NS
ndpointer(dtype=float), # r
This file has been truncated. show original
As it is shown pass the input inside a call to np.ascontiguousarray
def ppp(x):
x = np.ascontiguousarray(x, dtype=...)
1 Like
ferrad
February 14, 2024, 2:39pm
3
I didn’t want to try something completely new, instead I changed the list to numpy arrays. The syntax for the Fortran call for the (inout) variable is:
f(x.ctypes.data_as(ct.POINTER(ct.c_double)), ct.byref(objf))