My question is virtually identical to this one. However, I'm looking for a solution that uses Cython instead of ctypes.
I'm wrapping some legacy F77 code for using in Python. I've written wrappers for the subroutines, using a module and the iso_c_bindings, that I can then use from Cython. This works well for calling the subroutines, passing data as arguments, etc. However, I'd now like to access the common block data in the library directly from Cython.
So my question is two parts:
A) Can I access the common block data using Cython directly as in the ctypes example above? I so how? I gather I'm supposed to reference the common block as a struct using cdef extern
, but I'm not sure how to point to the library data.
B) Would I be better off, and not sacrifice performance, by simply writing setter/getter functions in my wrapper module? This was suggested in the responses to the ctypes question referenced above.
A) After trial & error, it seems that the following code works with python3.5/gfortran4.8/cython0.25 on Linux x86_64, so could you try it to see whether it works or not...?
fort.f90:
fort.h:
test.pyx:
setup.py:
compile:
test:
Here, please note that I did not include
z
intest.pyx
to check whether we can declare only selected variables in the common block. Also, some compiler options may be necessary to make the alignment of common variables consistent between C and Fortran (this YoLinux page may be useful).B) I guess it would depend on the amount of computation peformed by the Fortran routine... If the routine is heavy (takes at least a few minutes), copy operations in getter/setter may be no problem. On the other hand, if the routine finishes quickly while called a huge number of times, then the overhead may be non-negligible...
For efficiency, it might be useful to pass pointer variables from Cython to Fortran, get the address of selected
common
variables somehow byc_loc()
, and access them via pointers on the Cython side directly (though not still sure if it works...) But if there is no problem of memory alignment (for the compiler used), it may be more straight-forward to use structs as above.