I’m still new to Julia (and this discourse), but couldn’t find the answer to this question anywhere.
I have a large Fortran legacy code base which I’m trying to interface with a high-level language. I got something kind of working with Cython, and a MWE for that can be found on StackOverflow here: Fortran C interface for program containing non-c-interoperable derived type.
I’ve read/heard that interface C/Fortran to Julia is really simple, so I want to do the same sort of thing in Julia, I guess with ccall
, though I’m getting quite lost.
Here is some Fortran code,
module somemodule
use, intrinsic :: iso_c_binding
implicit none
type :: sometype
integer(c_int), allocatable :: a(:)
integer(c_int) :: b
end type
type, bind(c) :: someothertype
integer(c_int) :: c
end type someothertype
contains
! example routine that processes the content of the type
subroutine sometype_x2_f(x)
type(sometype), intent(inout) :: x
x%a = 2 * x%a
end subroutine
subroutine sometype_init_f(x, n)
type(sometype), intent(inout) :: x
integer(c_int), intent(in) :: n
integer(c_int) :: i
x%a = [(i, i=0, n)]
end subroutine sometype_init_f
integer(c_int) function sometype_sum_f(x) result(res)
type(sometype), intent(inout) :: x
res = sum(x%a)
end function sometype_sum_f
subroutine someothertype_x2_f(x)
type(someothertype), intent(inout) :: x
x%c = 2 * x%c
end subroutine
end module
which I can compile into a shared .so library and then call into a duplicate of someothertype in Julia:
mutable struct SomeOtherType
c::Cint
end
x = SomeOtherType(2)
println("x = $x (before)")
ccall((:__somemodule_MOD_someothertype_x2_f, "./libsometype_module.so"), Cvoid, (Ref{SomeOtherType},), x)
println("x = $x (after)")
which gives the expected
x = SomeOtherType(2) (before)
x = SomeOtherType(4) (after)
(hooray)
In my code, sometype%a
might be very large, so I would not want it duplicated in Julia (at least until I manage to rewrite the Fortran into Julia ;)). is there a way to keep the x%a
variable opaque to Julia (or otherwise avoid storing it twice, as I guess is done for someothertype%c
, e.g. with pointers) while still getting access to x%b
, and running (Fortran) functions that use/modify x%a
, such as sometype_x2_f
? Do I still need all the boilerplate code for wrapping these functions as I did in Cython (somemodule_wrap
in the SO thread and getter/setters for other variables e.g. x%b
)?