我可以编译这个Fortran代码“test.f90”。
作为一个例子,我想从julia中调用以下代码:
subroutine test(g,o)
double precision, intent(in):: g
double precision, intent(out):: o
o=g*g
end subroutine
使用
gfortran -shared -fPIC test.f90 -o test.so
并创建这个用于Julia的包装函数test.jl:
function test(s)
res=Float64[1]
ccall((:test_, "./test.so"), Ptr{Float64}, (Ptr{Float64}, Ptr{Float64}), &s,res);
return res[1]
end
并运行这些命令以获取所需的输出:
julia> include("./test.jl")
julia> test(3.4)
11.559999999999999
但我想返回一个数组而不是一个标量。我觉得我已经尝试了所有的方法,包括在这个答案中使用iso_c_binding。但是我尝试的所有方法都会向我抛出错误,看起来像这样:
ERROR: MethodError: `convert` has no method matching convert(::Type{Ptr{Array{Int32,2}}}, ::Array{Int32,2})
This may have arisen from a call to the constructor Ptr{Array{Int32,2}}(...),
since type constructors fall back to convert methods.
Closest candidates are:
call{T}(::Type{T}, ::Any)
convert{T}(::Type{Ptr{T}}, ::UInt64)
convert{T}(::Type{Ptr{T}}, ::Int64)
...
[inlined code] from ./deprecated.jl:417
in unsafe_convert at ./no file:429496729
作为一个例子,我想从julia中调用以下代码:
subroutine arr(array) ! or arr(n,array)
implicit none
integer*8, intent(inout) :: array(:,:)
!integer*8, intent(in) :: n
!integer*8, intent(out) :: array(n,n)
integer :: i, j
do i=1,size(array,2) !n
do j=1,size(array,1) !n
array(i,j)= j+i
enddo
enddo
end subroutine
直接更改参数似乎在从julia调用时没有什么用处,因此使用注释的变体也是一种选择。
那么我如何从Julia调用包含数组的Fortran子程序呢?
iso_c_binding
,那么你是指实际上使用了bind(C)
还是只是使用了iso_c_binding
模块?具体是哪种方式?哪段代码与问题中的错误信息相对应? - Vladimir F Героям славаinteger*8
不符合标准,也从未成为任何 ISO FORTRAN/Fortran 标准的一部分。您可以使用内置模块ISO_Fortran_env
中的命名常量INT64
或ISO_C_binding
中的C_INT64_T
,或者使用selected_int_kind
以安全可移植的方式使用大整数。 - jlokimlinarrays(:,:)
才能将数组从Python传递到被调用的子程序中。 - Jonatan Öström